Есть ли разница между `;` и `&&` и `|`?

Есть ли разница между `;` и `&&` и `|`?

Если вы хотите выполнить несколько команд, вы можете использовать ;, &&и|

Вот так: killall Finder; killall SystemUIServer, cd ~/Desktop/ && rm CachesИли: man grep | man catнапример.

Но есть ли разница между |, ;и &&? Если да, то в чем разница?

решение1

  • ;: команды, разделенные знаком a, ; выполняются последовательно. Оболочка ожидает завершения каждой команды по очереди.

  • &&: команда после &&выполняется, если и только если команда до &&возвращает статус выхода ноль. Вы можете думать об этом как ANDоб операторе.

  • |: канал. В выражении command1 | command2Стандартный вывод команды 1 подключается через канал к стандартному вводу команды 2.

Стоит упомянуть и другие подобные операторы управления:

  • ||: команда after ||выполняется только в том случае, если команда before ||возвращает ненулевой статус выхода. Вы можете думать об этом как об ORоператоре. Обратите внимание, что |и ||— совершенно разные животные.

  • &: оболочка выполняет команду, завершенную &в фоновом режиме, не дожидается завершения команды и немедленно возвращает код выхода 0. Опять же, &не имеет ничего общего с &&.

  • |&: сокращение для 2>&1 |ie, т.е. стандартный вывод и стандартная ошибка команды command1 подключены к стандартному вводу команды command2 через канал.

Кроме того, если вы используете zsh, то вы также можете начать команду с &|или &!. В этом случае задание немедленно отменяется, после запуска оно не имеет места в таблице заданий.

решение2

Рассмотрим две команды Aи B. Когда вы пишете

A | B

Aи Bвыполняются параллельно, а стандартный вывод Aотправляется как стандартный ввод B.

Когда ты пишешь

A; B

Aвыполняется, затем Bвыполняется (если только set -eне был использован и Aне завершается с ненулевым статусом выхода, в этом случае оболочка завершается сразу после A).

Когда ты пишешь

A && B

Aвыполняется, затем Bвыполняется только если Aуспешно завершился (нулевой статус выхода). Эта форма может быть безопаснее предыдущей, например, с

cd some_dir && rm file*

Гарантирует &&, что удалены нужные файлы, т. е. файлы удаляются только в случае cdуспешного завершения.

решение3

В других ответах уже объяснено |, &&и ;, поэтому я добавлю кое-что дополнительное, о чем вы явно не просили: ||.

A || B

Aвыполняется, а затем Bвыполняется только в случае Aнеудачи. Это полезно для реагирования на ошибочные состояния:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

(Это 2>/dev/nullнеобходимо для того, чтобы скрыть само сообщение об ошибке rm.)

решение4

Никто, похоже, не объясняет, почему вы используете каждый из них, учитывая ваши реальные примеры. Я попробую:

killall Finder; killall SystemUIServer

Команда типа killallможет занять некоторое время для выполнения. Используя точку с запятой, вы можете дать обе команды одновременно, а затем сделать что-то еще, пока ждете. Таким образом, вам не придется ждать дважды (по одному разу для каждой команды).

cd ~/Desktop/ && rm Caches

Вы хотите удалить каталог ~/Desktop/Cachesи оказаться в каталоге ~/Desktop. Чего вы не хотите делать, так это удалять каталог Caches из текущего каталога (до того, как вы его измените). Поэтому вы используете , &&чтобы проверить, что изменение каталога было успешным, прежде чем вы выполните команду remove.

man grep | man cat

Для меня это не имеет смысла. manКоманда не обрабатывает ввод, поэтому передача ей данных по конвейеру ничего не даст. Возможно, вы имели в виду

man grep || man cat

Это попыталось бы найти страницу руководства для grepи затем, если бы не удалось, то показало бы страницу руководства для cat. Или, возможно, вы имели в виду

man grep | cat

Это будет использоваться catдля отображения страницы руководства, а не пейджера (обычно less). |Перенаправляет вывод из manв команду cat(которая просто выводит все на экран). Это может быть полезно в графическом интерфейсе, где вы можете использовать полосу прокрутки для перемещения вперед и назад по файлу вместо использования клавиатурных команд в less.

Примечание: если вы хотите знать, что ; && | ||делать в более общих случаях, то я бы посоветовал посмотреть на ответ jimmij. Я просто пытаюсь объяснить, что происходит в примерах из вопроса.

Связанный контент