Как мне объединить команды в консоли?

23

В некоторых случаях bashя хочу запускать несколько команд последовательно и не хочу ждать, пока они завершатся, прежде чем набирать новые. Поэтому я делаю что-то вроде этого:

cmd1; cmd2; cmd3

К сожалению, одна из команд может потерпеть неудачу. В таком случае я бы хотел остановиться. Есть ли простой способ сделать это, но сделать так, чтобы я продолжал выполнять команды, только если предыдущая команда имела код завершения 0?

питоническая метафора
источник
Вот отличный ответ от Unix SE.
НелинейныйФрукт

Ответы:

39

Используйте &&оператор,

cmd1 && cmd2 && cmd3

В shellscripting, &&и ||операторы по образцу оптимизированной реализации логических операторов в C. &&Средства и оператора, а также ||средства ИЛИ. Unix тесно связан с C, а в C второй операнд логических операторов не оценивается, если результат уже известен из первого операнда. Например "false && x", falseдля любого x, поэтому нет необходимости оценивать x(особенно, если xэто вызов функции); аналогично для "true || x". Это также называется семантикой короткого замыкания .

А в Unix традиционно интерпретировать возвращаемые значения команд как истинные значения «успешного завершения»: код выхода 0 означает true(успех), ненулевое значение false(сбой). Таким образом, когда первая команда в cmd1 && cmd2возврате "false"(ненулевой статус выхода, который указывает на сбой), статус составной команды известен: сбой. Таким образом, общая интерпретация cmd1 && cmd2 может быть: «выполнить cmd1, а затем, если это не сработало cmd2». Что именно вы хотите в своем вопросе?

Аналогично с OR: cmd1 || cmd2можно интерпретировать как «выполнить cmd1, ИЛИ если не получится cmd2».


Подсказка: для более длинных цепочек &&, подумайте над тем , чтобы set -eвставить свой сценарий. Это в основном меняет точку с запятой ;на &&пару особых случаев.

ulidtko
источник
1
+1 для объяснения||
Alp
Можете ли вы соединить в цепочку статус первой команды? (успех или неудача)
Уго Тренто
@HugoTrentesaux что вы имеете в виду? .. Результат успеха / неуспеха или A || Bточно такой же , как [короткое замыкание] логического А или В . A || Bэто успех , когда Aбыл успех , или когда Aбыл провал , но Bбыл успех ; и A || Bэто провал, когда Aбыл провал и Bбыл failure. Аналогично для &&, следует логическое И.
ulidtko
В контексте оболочки, как я могу выполнить A, а затем B, независимо от того, провалился ли A или преуспел?
Уго Трентесо
1
@HugoTrentesaux это то, что обычная регулярная ;(или новая строка ) делает по умолчанию. set -eпревратится ;в &&, грубо говоря. set +e[по умолчанию] превращается A; Bв то, что вы говорите: беги A, потом неважно, что беги B.
Улидько
13

«Цепные команды группируют их»

ping 192.168.0.1 || { echo "ping not successful"; exit 1; }

ping, только если он не успешен, выполняет цепочечную группу команд в скобках.

Внимание:

Список должен заканчиваться символом «;».

Между скобками и сгруппированными командами должны быть пробелы!

и я
источник
6

Просто с &&оператором. Например:

cmd1 && cmd2 && cmd3

В случае сбоя одной из команд (возвращает значение выхода, отличное от 0), другие команды не будут выполняться.

Wuffers
источник