Що краще: використовувати; або && виконувати кілька команд в одному рядку?


427

У навчальних посібниках та підручниках я часто бачу комбіновані команди. Наприклад,

sudo apt-get update && sudo apt-get install pyrenamer

Там , здається, чотири можливих роз'ємів: &, &&, ||і ;. Хоча & для мене роз'єм зрозумілий (він надсилає процес на задній план і залишає термінал доступним), незрозуміло, в чому різниця між &&і ;. І я не знав ||до коментаря Каї.

Наступні питання стосуються різниці між двома роз'ємами, але це робиться переважно в коментарях:

Ось ось низка суміжних питань:

  1. У чому різниця між ;і &&?
  2. Коли слід використовувати їх відповідно? Було б непогано бачити деякі випадки використання: якщо я хочу запустити команду, а потім після відключення мого комп’ютера, який з'єднувач слід вибрати?
  3. Які їх переваги та небезпеки ? У коментарі до цієї відповіді Робі Басак зазначає, що така команда може мати руйнівні наслідки, якщо, наприклад, не вдасться перший елемент в командному ланцюгу.cd /somewhere_else; rm -Rf *
  4. Якщо доречно, звідки вони беруться?

7
Є ще один роз'єм, до якого ви, можливо, не натрапили: ||такий же, як, &&за винятком того, що він виконує лише другу команду, якщо перша закінчилася з ненульовим (невдалим) статусом.
Кая

4
Також зауважте, що запуск вашого сценарію set -eзупинить сценарій при відмові, як якщо б всі команди були пов'язані &&.
choroba


3
Ніхто не відповів Qn 4 ... Я підозрюю поведінку && та || був натхненний мовою програмування на С. У випадку (x&& y), якщо x оцінюється як false, весь вираз повинен бути хибним, щоб компілятор міг оптимізувати оцінку y, якщо це було дорого. Сучасні стандарти C і C ++ насправді вимагають цієї оптимізації, тому програми можуть сміливо припускати, що y не буде оцінюватися, якщо x помилково. Наприклад, (ptr && ptr-> days> 31) не вийде з ладу, навіть якщо ptr недійсний. Також у С твердження закінчуються на; незалежно від того, є ще одне твердження в тому ж рядку чи ні.
Кевін

Відповіді:


771

Шпаргалку:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.

19
І звичайно A & B &: Запустіть A у фоновому режимі, потім запустіть B у фоновому режимі (незалежно від успіху) і поверніть контроль до оболонки. Це часто працює приблизно так само, як запуск обох процесів одночасно.
Обмежене спокутування

4
чи можна сказати: запустити a у фоновому режимі, а потім b у фоновому режимі, лише якщо працює? (Я здогадуюсь &&&?)
користувач230910

14
@ user230910: це було б (A && B) &.
близько

5
Чи можете ви посилатися на це авторитетний документ?
Хайме Хаблуцель

@Jack Коли виконується з Cronjob, він не зовсім відповідає цьому правилу, будь-яка ідея чому? Для файлу python
CodeGuru

77

&&виконує другу команду лише в тому випадку, якщо перша вийшла зі статусом 0 (була успішною). ;виконує обидві команди, навіть якщо перша закінчується з ненульовим статусом.

Ваш приклад з &&може бути так само перефразований як

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi

Дякую. Я оновив це питання, щоб переконатися, що різні підпитання легко розрізнити.
don.joey

5
@Private: Ви повинні використовувати, ;якщо для успішної роботи другої команди не потрібна попередня.
choroba

31

Використання ;виконує команди незалежно від того, успішна чи ні перша команда.

використовуючи &&команду Execute 2nd, лише коли перша команда успішно виконана (статус 0).

Обидва використовуються з різної точки зору. Як і для більш тривалого процесу, скажімо, що для установки вам потрібно зібрати та встановити. ви повинні make && make install. Тож установка запуститься лише в разі makeуспіху.

Тож для залежних команд ви повинні використовувати &&

Введіть bash або команди з незалежними командами ;

Тож якщо ви хочете вимкнути комп’ютер, навіть перше завдання не вдалося використовувати ;, але якщо ви хочете на повний успіх першого завдання, ініціюйте використання вимкнення&&


14

a ; bзапустить b незалежно від стану виходу a. a && bзапустить b лише за умови успіху.

Це необхідно і достатньо для відповіді на перші 3 питання. Зокрема, 2 занадто широкі, і на нього не можна надати остаточну відповідь "однієї" - найкраще ставити рішення залежно від конкретного випадку.

Щодо четвертого питання: Вони синтаксис Баша .

Внутрішньої небезпеки немає і при використанні. Знову ж таки, визначення вище є достатнім. Це означає, що ви будете писати, &&коли bмає ненавмисні ефекти, якщо aце не вдасться. Не потрібно ніяких додаткових правил чи пояснень, ІМХО.


1

A; B # Виконати A, а потім B, незалежно від успіху A

&& B # Виконати B, якщо і лише тоді, коли A вдалося

А || B # Виконати B, якщо і тільки якщо A не вдалося

Виконання & # у фоновому режимі.

Дуже хороше правило. Я б додав, що в деяких випадках використання цих команд в підрозділі має сенс, коли ми хочемо розглядати їх як єдину одиницю або не хочемо з'єднувати деякі результати операцій з поточною оболонкою.

Приклади:

-поєднати вихід двох команд:

(ls foo; ls bar) > single-result.txt

-вхід до каталогу та виконання команди звідти, не змінюючи поточного каталогу оболонки:

(cd target-directory && jar -xf ../my-jar)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.