Яка мета "&&" в команді shell?


354

Наскільки я знаю, використання &після команди - для запуску її у фоновому режимі.

Приклад &використання:tar -czf file.tar.gz dirname &

Але як щодо &&? (подивіться на цей приклад: /server/215179/centos-100-disk-full-how-to-remove-log-files-history-etc#answer-215188 )

Відповіді:


398

&&дозволяє зробити щось на основі того, чи успішно виконана попередня команда - саме тому ви схильні бачити її як прикуту do_something && do_something_else_that_depended_on_something.


391

Крім того, ви також маєте, ||що є логічним або, а також ;який є лише роздільником, який не байдуже, що сталося з командою раніше.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Деякі деталі про це можна знайти тут Списки команд у Посібнику з Bash.


5
Можливо, ви хочете додати false && echo "Will not be printed".
МТСан

112

командний рядок - яка мета &&?

У оболонці, коли бачиш

$ command one && command two

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

Він має намір запобігти запуску другого процесу, якщо перший не вдався.

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

Ваша оболонка вважає повернене значення 0 істинним, інші додатні числа - хибними

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

&&Згадуються як AND_IFв граматиці POSIX оболонки , яка є частиною and_orсписку команд, які також включають в себе, ||який є OR_IFз подібною семантикою.

Граматичні символи, цитовані з документації:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

І Граматика (також цитується з документації), яка показує, що будь-яку кількість AND_IFs ( &&) та / або OR_IFs ( ||) можна з'єднати (як and_orвизначено рекурсивно):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Обидва оператори мають однаковий пріоритет і оцінюються зліва направо (вони ліво-асоціативні). Як кажуть документи:

AND-ORСписок являє собою послідовність з одного або декількох конвеєрів , розділених операторами "&&"і "||".

Список являє собою послідовність з одного або декількох І-АБО - листи відокремлені один від операторів ';'і '&'і необов'язково припинено ';', '&'або.

Оператори "&&"і "||"мають однаковий пріоритет і повинні бути оцінені з левоассоціатівностью. Наприклад, обидві наступні команди записують виключно бар на стандартний вихід:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. У першому випадку false - це команда, яка закінчується зі статусом 1

    $ false
    $ echo $?
    1

    що означає, echo fooщо не працює (тобто короткочасне керуванняecho foo ). Потім команда echo barвиконується.

  2. У другому випадку істинний вихід із кодом 0

    $ true
    $ echo $?
    0

    і тому echo fooне виконується, тоді echo barвиконується.


31

Досить поширеним використанням для && є складання програмного забезпечення з автоінструментами. Наприклад:

./configure --prefix=/usr && make && sudo make install

В основному, якщо конфігурація проходить успішно, зробити компіляцію make run запустити, і якщо це вдасться, make запустити як root для встановлення програми. Я використовую це, коли я здебільшого впевнений, що все буде працювати, і це дозволяє мені робити інші важливі речі, такі як перегляд stackoverflow, а не "моніторинг" прогресу.

Іноді я дійсно захоплююся ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Я роблю це, коли, наприклад, роблю Linux з нуля.


2
Добре в REPL, але для сценаріїв я віддаю перевагу set -o errexitBash.
Франклін Ю

19

&&рядки команд разом. Послідовні команди виконуються лише у випадку успіху попередніх.

Аналогічно, ||дозволить виконати послідовну команду, якщо попередня помилка.

Див. Програмування Bash Shell .


8

Дивіться приклад:

mkdir test && echo "Something" > test/file

Shell спробує створити каталог testі тоді, лише якщо це було успішним , спробує створити файл всередині нього.

Таким чином, ви можете перервати послідовність кроків, якщо один з них не вдався.


8

Виконати друге твердження, якщо перше твердження закінчиться успішно. Як у випадку заяви:

 if (1 == 1 && 2 == 2)
  echo "test;"

Її спочатку намагаються, якщо 1 == 1, якщо це правда, то вона перевіряє, чи 2 == 2


1
Чи може хтось пояснити, чому це було сприйнято тим, що користувачі натрапляють на це питання?
користувач3243242

1
@ user3243242 це не помиляється, лише поганий приклад для ілюстрації використання&&
дан

Це прекрасне розуміння того, як ifпрацюють тести на баш. Я ніколи не думав про це як про ланцюжок команд порівняння, що розривається, коли будь-яка з них виходить з ладу. Отже, ви отримали мою пропозицію :)
PiRK

1
Наслідок полягає в тому, що ви можете отримати протилежну поведінку, використовуючи ||для ланцюга команд, поки одна з них не вдається: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: виконати команду_2 лише тоді, коли команда_1 виконана успішно.

command_1 || command_2: виконати команду_2 лише тоді, коли команда_1 не виконана успішно.

Схоже на те, як виконується умова "якщо" на мові програмування, наприклад, в if (condition_1 && condition_2){...}умові_2 буде пропущено, якщо умова_1 є, falseа в if (condition_1 || condition_2){...}умові_2 буде опущено, якщо умова_1 є true. Бачите, це той самий трюк, який ви використовуєте для кодування :)


Я не знаю, що ви маєте на увазі під «прямо протилежним», але $ echo '1' || echo '2' друкує лише '1'. і $ неправильно_команда || echo '2' друкує повідомлення про помилку та '2' у наступному рядку. Чи можете ви пояснити трохи більше про те, що ви вважаєте неправильним у цьому?
Сяонін Лі

Хоче чувак, я, звичайно, вчора був занадто стомлений. Вибачте за це, це був лише я: / Мені потрібно, щоб ви щось відредагували у відповіді, якщо хочете, щоб я підняв (щоб відповісти 0, зараз stackoverflow просити редагувати, тому я не можу)
Arount

@Arount, це нормально, не хвилюйся. Тож я просто подав правку. тож чи можете ви зараз зняти голосування за програму?
Сяонін Лі

так, знову ж таки, вибачте, справді
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

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


Ласкаво просимо в stackoverflow. Переконайтеся, що фрагмент коду працює, перш ніж публікувати тут. Ви повинні виправити цеif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Чжен Ку

1
Дякую @ZhengQu за вашу команду, це було зроблено.
Амін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.