
Если вы хотите выполнить несколько команд, вы можете использовать ;
, &&
и|
Вот так: 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. Я просто пытаюсь объяснить, что происходит в примерах из вопроса.