Какова цель «&&» в команде оболочки?

Ответы:

399

&&позволяет вам что-то делать, основываясь на том, была ли предыдущая команда выполнена успешно, поэтому вы склонны видеть ее в цепочке do_something && do_something_else_that_depended_on_something.

girasquid
источник
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.

plundra
источник
5
Может быть, вы хотели бы добавить false && echo "Will not be printed".
МТСан
112

командная строка - какова цель &&?

В раковине, когда вы видите

$ command one && command two

Цель состоит в том, чтобы выполнить команду, которая следует &&только в том случае, если первая команда выполнена успешно. Это идиоматично для оболочек Posix, а не только в Bash.

Он намерен предотвратить запуск второго процесса в случае сбоя первого.

Вы можете заметить, что я использовал слово «намерение» - это не зря. Не все программы имеют одинаковое поведение, поэтому для того, чтобы это работало, вы должны понимать, что программа считает «неудачей» и как она ее обрабатывает, читая документацию и, при необходимости, исходный код.

Ваша оболочка считает возвращаемое значение 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. Во втором случае true выходит с кодом 0

    $ true
    $ echo $?
    0

    и, следовательно echo foo, не выполняется, то echo barвыполняется.

Аарон Холл
источник
31

Для & & 'довольно часто используется компиляция программного обеспечения с помощью автоинструментов. Например:

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

В основном, если конфигурация завершается успешно, make запускается для компиляции, а если это успешно, make запускается от имени пользователя root для установки программы. Я использую это, когда я в основном уверен, что все будет работать, и это позволяет мне делать другие важные вещи, такие как просмотр стека и не отслеживание прогресса

Иногда я действительно увлекаюсь ...

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

Я делаю это, например, когда делаю Linux с нуля.

Найджел Аткинсон
источник
2
Хорошо в REPL, но для скриптов я бы предпочел set -o errexitдля Bash.
Франклин Ю
19

&&Строки команды вместе. Последовательные команды выполняются только в случае успеха предыдущих.

Точно так ||же позволит последующей команде выполнить, если предыдущая не удалась.

Смотрите Программирование Bash Shell .

Дин Бердж
источник
8

Смотрите пример:

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

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

Таким образом, вы можете прервать последовательность шагов, если один из них не удался.

ALNO
источник
8

Это выполнение второго оператора, если первый оператор заканчивается успешно. Как если бы заявление:

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

Его первая попытка, если 1 == 1, если это правда, он проверяет, если 2 == 2

Ник
источник
1
Может ли кто-нибудь объяснить, почему за это проголосовали пользователи, которые наткнулись на этот вопрос?
user3243242
1
@ user3243242 это не так, просто плохой пример, чтобы проиллюстрировать использование&&
дан
Это отличное понимание того, как ifтесты работают в bash. Я никогда не думал об этом как о цепочке команд сравнения, которые ломались, когда любая из них терпела неудачу. Итак, у вас есть мое мнение :)
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
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 за вашу команду, это было сделано.
Амин