Зачем запускать команду оболочки Linux с '&'?

30

Я использую Red Hat Linux Enterprise версии 5. Я заметил, что люди иногда запускают команды с несколькими &опциями. Например, в приведенной ниже команде есть два &знака. Какова цель их? Они всегда используются вместе с nohup?

nohup foo.sh <script parameters> >& <log_file_name> &
George2
источник

Ответы:

15

В дополнение к ответам Мартина, Эша и Кевина, иногда вы увидите амперсанд, используемый математически для побитового И * :

$ echo $(( 11 & 7 ))
3

Если вы не знакомы с битовыми операторами:

11: 1011
 7: 0111
-------- AND
 3: 0011

В каждой позиции есть один бит в первом числе и второе число, установите этот бит в единицу в ответе.

* Функция в ответе Кевина называется логическим AND.

Чтобы уточнить ответ Эша, при использовании перенаправления амперсанд может указать оболочке скопировать дескриптор файла. В этой команде echo "hello" > outputfile 2>&1амперсанд заставляет любой вывод, который может идти в стандартную ошибку (stderr, дескриптор файла 2), идти в то же место, что и стандартный вывод (stdout, дескриптор файла 1, по умолчанию для левой части >). >& outputfileОператор обсчитывать для > outputfile 2>&1.

Кроме того , новый в Bash 4, есть два новые терминаторов для положений в caseкоманде ;&и ;;&которые влияют на «проваливается» ли дело , и если да, выполняется ли следующее испытание.

Приостановлено до дальнейшего уведомления.
источник
Круто, Деннис! Предположим, я использую логин терминала ssh на машине, затем использую терминал ssh для выполнения команды (предположим, что это длительный процесс), а затем, если я выйду из сеанса терминала, то длительный процесс команды будет завершен правильно? И если я хочу, чтобы команда продолжала выполняться, даже если я выйду из оболочки, я должен использовать nohup или & (в конце команды) или использовать оба nohup и &?
George2
1
@ George2: Нет, >& filenameвыводит stdout и stderr в один и тот же файл. Если вы хотите перенаправить только stderr (и оставить stdout в покое), вы должны это сделать 2> filename. Что касается вашего другого вопроса, скорее всего, вы бы использовали оба nohupи &.
Приостановлено до дальнейшего уведомления.
1
@ George2: Если вы не выполняете фоновую команду, вы не получите приглашение оболочки, поэтому вы можете выполнить команду logoutили exit.
Приостановлено до дальнейшего уведомления.
2
Джордж: Если вы не используете &, то вы никогда не получите подсказку, чтобы сделать что-нибудь еще. Терминал будет «зависать» до тех пор, пока процесс (что бы это ни был) не завершится или не будет завершен / уничтожен & Гарантирует, что процесс выполняется в фоновом режиме. Однако, если вы выйдете из системы, операционная система завершит все ваши процессы, что также убивает ваш фоновый процесс. Если вы используете nohup, вы говорите процессу «игнорируйте команду, которая прекратит вас».
Мартин Маркончини
1
@ George2: да. "невосприимчив к зависаниям" == "процесс продолжается" и "non-tty" == "выйти из сеанса консоли терминала"
приостановлено до дальнейшего уведомления.
32

В сценарии оболочки Bash амперсанд «&» используется для разветвления процессов:

find -name hello &

Это приведет к тому, что команда find будет разветвлена ​​и запущена в фоновом режиме (вы всегда можете убить ее по ее PID).

Мартин Маркончини
источник
Благодаря Мартину, предположим, что я использую логин терминала ssh на машине, затем использую терминал ssh для выполнения команды (предположим, что это длительный процесс), затем, если я выйду из сеанса терминала, то длительный процесс команды будет завершен правильно ? И если я выполню команду, используя & в терминале ssh, даже если я выйду из терминала, долгосрочный процесс команды все еще выполняется, правильно?
George2
1
Это правильно, Джордж. Фоновые процессы должны продолжаться до тех пор, пока они не завершатся или вы не убьете их. Однако, как уже было сказано, вам не понадобится nohup, чтобы избежать смерти процесса при выходе пользователя из системы.
Мартин Маркончини
Спасибо Мартин! Я хочу знать, почему нам нужно использовать и &, и nohup, и каковы их отдельные функции, которые позволяют нам достичь цели, позволяющей команде продолжать работать, даже если консоль терминала закрывается. Я читаю man-страницу nohup, и там упоминается «запустить команду, защищенную от зависаний, с выводом на не-tty». Я не совсем понимаю, означает ли это то, что вы имеете в виду, что иммунитет к зависаниям позволяет команде продолжать работать без влияния quit терминальная консоль? Если это так, я думаю, что достаточно использовать nohup, и нет необходимости использовать &. Любые комментарии?
George2
1
Вам нужно использовать Оба, если вы не используете &, терминал не позволит вам вводить какие-либо другие команды. Лучший способ увидеть это - просто попробовать. Хорошим примером является команда, которая занимает некоторое время, например find: find -name SomeName /> somefile.txt, попробуйте это с помощью nohup и & и увидите различия.
Мартин Маркончини,
Это отличный ответ на вопрос о nohup: serverfault.com/questions/311593/…
joshperry
26

Зачем запускать команду оболочки Linux с '&'?

Для немедленного получения вашего приглашения и запуска процесса в фоновом режиме.

Каковы их функции?

nohup позволяет фоновому процессу продолжать работу даже после выхода пользователя из системы (или выхода из инициирующей оболочки).

> & перенаправляет как стандартный вывод, так и стандартную ошибку в файл журнала.

& запускает все это в фоновом режиме, давая вам ваш ответ немедленно.

Объяснение:

Каждый процесс Linux открывает три канала ввода-вывода, вход «stdin», стандартный вывод «stdout» и стандартный вывод ошибок «stderr». Их можно использовать для двоичного кода, но они традиционно являются текстовыми. Когда большинство программ видит stdin close, они закрываются (это может изменить программист).

Когда родительская оболочка завершается, stdin закрывается для дочерних элементов, и (часто обычно) дочерние элементы также выходят. Кроме того, дети получают программный сигнал SIGHUP, указывающий, что пользователь "завис" (ранее модем), и по умолчанию здесь также происходит выход. (Обратите внимание, программист может изменить все это при написании программы).

Итак, что делает nohup, так это предоставляет дочернему процессу отдельную среду ввода-вывода, связывая входы и выходы с чем-то, не привязанным к родительской оболочке, и защищая дочерний процесс от сигнала SIGHUP. Как только пользователь отключится, вы увидите фоновый процесс nohup, принадлежащий init (процесс 1), а не оболочка пользователя.

Однако nohupне может выполнить работу полностью, если процесс выполняется на переднем плане, поэтому &используется для запуска программы в фоновом режиме, где она может успешно работать с или без входа в систему пользователя.

kmarsh
источник
Предположим, я использую логин терминала ssh на машине, затем использую терминал ssh для выполнения команды (предположим, что это длительный процесс), а затем, если я выйду из сеанса терминала, то длительный процесс команды будет завершен правильно? И если я хочу, чтобы команда продолжала выполняться, даже если я выйду из оболочки, я должен использовать nohup или & (в конце команды) или использовать оба nohup и &?
George2
1
Правильно, используйте nohup и & для продолжения процесса после отключения SSH.
Кмарш
Спасибо, Kmarsh! Я хочу знать, почему нам нужно использовать и &, и nohup, и каковы их отдельные функции, которые позволяют нам достичь цели, позволяющей команде продолжать работать, даже если консоль терминала закрывается. Я читаю man-страницу nohup, и там упоминается «запустить команду, защищенную от зависаний, с выводом на не-tty». Я не совсем понимаю, означает ли это то, что вы имеете в виду, что иммунитет к зависаниям позволяет команде продолжать работать без влияния quit терминальная консоль? Если это так, я думаю, что достаточно использовать nohup, и нет необходимости использовать &. Любые комментарии?
George2
1
Я отредактирую свой ответ, чтобы ответить.
kmarsh
13

В дополнение к ответу @ Martin: Другое использование амперсанда ( >&как указано выше) заключается в захвате обоих stdoutи stderr. Обычно, если вы перенаправили вывод в файл только с «>», вы получите только вывод stdout, пропустив все ошибки.

ясень
источник
1. Спасибо, Эш, я хочу подтвердить, что "> & <имя файла журнала>" сбросит все stderr и stdout в файл журнала, правильно? 2. А использование «> <имя файла журнала>» сбросит весь стандартный вывод в файл журнала, правильно?
George2
1
@ Джордж: Да, все верно.
Эш
Спасибо Эш! Я хочу знать, почему нам нужно использовать и &, и nohup, и каковы их отдельные функции, которые позволяют нам достичь цели, позволяющей команде продолжать работать, даже если консоль терминала закрывается. Я читаю man-страницу nohup, и там упоминается «запустить команду, защищенную от зависаний, с выводом на не-tty». Я не совсем понимаю, означает ли это то, что вы имеете в виду, что иммунитет к зависаниям позволяет команде продолжать работать без влияния quit терминальная консоль? Если это так, я думаю, что достаточно использовать nohup, и нет необходимости использовать &. Любые комментарии?
George2
4

В дополнение к ответу Мартина и Эша, иногда вы можете увидеть использование &&токена. Это используется, чтобы сказать «выполнить вторую команду тогда и только тогда, когда первая команда была выполнена успешно». Хорошо написанная команда, если она имеет какие-либо ошибки, не завершится успешно.

[kevin@box ~]$ ls file && echo removing file && rm file
ls: file: No such file or directory
[kevin@box ~]$ touch file
[kevin@box ~]$ ls file && echo removing file && rm file
file
removing file
[kevin@box ~]$
Кевин М
источник
Круто, Кевин! Предположим, я использую логин терминала ssh на машине, затем использую терминал ssh для выполнения команды (предположим, что это длительный процесс), а затем, если я выйду из сеанса терминала, то длительный процесс команды будет завершен правильно? И если я хочу, чтобы команда продолжала выполняться, даже если я выйду из оболочки, я должен использовать nohup или & (в конце команды) или использовать оба nohup и &?
George2
Либо один будет работать. Я думаю, что NOHUP был оригинальным способом сделать это (но я полностью догадываюсь), но фон теперь работает. Важным отличием является запуск интерактивной оболочки с помощью sshing в удаленной системе. Процесс NOHUP будет выполняться на переднем плане, но продолжит работу, если вы выйдете, тогда как фоновый процесс вернется сразу после того, как вы породили команду. Но когда вы пытаетесь выйти из интерактивной оболочки с командой, работающей в фоновом режиме, вы сначала получаете предупреждение.
Кевин М
2

Ответ Мартина хороший, но немного двусмысленный. Команда всегда форк-и исполняется, но нормальным поведением оболочки является ожидание команды до ее выхода. Амперсанд помещает его в фоновый режим, чтобы вы вернули подсказку своему терминалу и могли делать другие вещи. Если процесс выплескивает данные в stdout или stderr, это будет смешано с тем, что вы делаете в приглашении, и может сбить вас с толку. Вот почему вы перенаправляете затем с помощью> & /path/to/logfile.txt.

В ответ на George2 нормальным поведением для выхода из оболочки является отправка сигнала SIGHUP всем процессам в одной и той же группе процессов (в основном вещи, которые вы породили), и они обычно завершаются. Если вы хотите, чтобы это продолжалось, даже если вы закрываете процесс оболочки, вы можете использовать команду nohup, чтобы они игнорировали этот сигнал и продолжали работать. Для этого типа процесса есть специальное имя, которое называется процессом демона (произносится как «демон»).

Рич Гомолка
источник
Спасибо, Рич! Предположим, я использую логин терминала ssh на машине, затем использую терминал ssh для выполнения команды (предположим, что это длительный процесс), а затем, если я выйду из сеанса терминала, то длительный процесс команды будет завершен правильно? И если я хочу, чтобы команда продолжала выполняться, даже если я выйду из оболочки, я должен использовать nohup или & (в конце команды) или использовать оба nohup и &? И почему?
George2
Эй, Джордж, извини, я так поздно отвечаю. Да, если вы выйдете из оболочки, длительный процесс будет прерван. Если вы хотите, чтобы он продолжал работать, вам нужно выполнить nohup (чтобы он не прерывался при закрытии оболочки) и & (чтобы поместить в фоновый режим, чтобы вы могли использовать Crtl-D или выйти из своей оболочки). Вы также можете посмотреть на команду setsid, которая позволит вашему процессу выполняться, игнорируя SIGHUP немного другим способом.
Rich Homolka
Отличный ответ, объясняет лучшие практики для запуска процессов в фоновом режиме.
Марсель Вальдес Орозко