Что означает & в конце команды?

12

У меня есть строка сценария запуска:

pyprogramm >> /dev/null  2>&1 &

Значения:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

но что значит самый последний &?

Вико
источник

Ответы:

16

Что такое терминатор?

Трейлинг- &оператор в конце команды используется для перевода команд в фоновый режим. На самом деле это стандартный синтаксис, определенный стандартом POSIX :

Асинхронные списки

Если команда завершается оператором управления ('&'), оболочка должна выполнить команду асинхронно в подоболочке. Это означает, что оболочка не должна ждать завершения команды перед выполнением следующей команды.

Формат для запуска команды в фоновом режиме:

команда1 & [команда2 & ...]

Целью фоновых команд является выполнение команды без основной оболочки в сценарии или интерактивной оболочки в ожидании команды, которая блокирует выполнение других команд и создает неудобства для пользователя в ожидании. Это удобно для запуска длительных команд, но вам нужно продолжить работу в текущей оболочке. Как вы можете догадаться, это произошло в то время, когда не было эмуляторов терминалов с несколькими вкладками, но терминалы были фактическим физическим оборудованием, подключенным к самому компьютеру.

Из определения вы можете видеть, что он &также служит терминатором команды для списков команд, так же, как и ;делает. В вашем конкретном примере pyprogramm >> /dev/null 2>&1 &в списке есть только одна команда.

Последовательный; списки против асинхронных и списки

В более общем смысле,

echo Hello ; echo World ;

и

echo Hello & echo World &

являются двумя примерами списков останавливали ;и &операторов. Одно из отличий состоит в том, что &завершенный список будет связан с входом, /dev/nullесли управление заданиями отключено:

Если управление заданиями отключено (см. Set, -m), считается, что стандартный ввод для асинхронного списка перед выполнением любых явных перенаправлений назначен файлу с такими же свойствами, что и / dev / null. Этого не должно быть, если включен контроль заданий. Во всех случаях явное перенаправление стандартного ввода должно переопределять это действие.

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

Также обратите внимание, что из определения, которое мы упоминали ранее, &выполняет команды в подоболочке. Напротив, ;завершенный список выполняется в текущей оболочке. Также есть разница в статусах выхода. Для &стандарта говорится:

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

Это важно, когда вы хотите поместить несколько команд в фоновом режиме. Когда вы пишете сценарий или команду, вам придется выбирать команды, для которых вам все равно, потерпели ли они неудачу или нет, или вам придется искать способ обработки ненулевого (ошибочного) состояния выхода. В вашем конкретном примере pyprogramm >> /dev/null 2>&1 &работа в фоновом режиме должна иметь какой-то способ указать, произошел ли сбой или нет, однако, судя о том, что вы используете, 2>&1вы скрываете вывод ошибок путем перенаправления, и вы, вероятно, предполагаете, что скрипт не должен завершиться сбоем.

Напротив, ;статус выхода определяется как:

Статусом выхода последовательного списка должен быть статус выхода последней команды в списке.

Опять же, это влияет на то, как вы пишете последовательный список команд в командной строке, и на то, как вы хотите, чтобы что-то обрабатывалось в случае сбоя некоторых команд в списке.


Дополнительные заметки и дополнительное чтение

  • Дело в том , что это средство определения POSIX , что все Bourne-подобных оболочек, имея в виду bash, dashи kshдолжны поддержать его.

  • &в перенаправлении отличается от &команды терминатора. Это означает дублирование (копирование) объекта дескриптора файла. См. Что именно означает и означает в перенаправлении вывода?

  • Там bashтакже есть |&оператор (обратите внимание, что между трубой и амперсандом нет места). Из руководства по bash :

    Если используется | &, стандартная ошибка команды, в дополнение к стандартному выводу, подключается к стандартному вводу command2 через канал; это сокращение для 2> & 1 |. Это неявное перенаправление стандартной ошибки на стандартный вывод выполняется после любых перенаправлений, указанных в команде.

Сергей Колодяжный
источник
2
То, что вы говорите о &сокрытии вывода, звучит неправильно. Абзац из стандарта, который вы цитируете, говорит о вводе , а не выводе . Причина различия между включением или отключением управления заданиями заключается в том, что фоновый процесс, пытающийся прочитать данные с tty, будет приостановлен. В этот момент вам нужно использовать управление заданиями, чтобы поместить его на передний план, чтобы обеспечить ожидаемый ввод. Все это не может быть выполнено без контроля заданий, и поэтому, если контроль заданий отключен, стандартный ввод должен быть перенаправлен /dev/nullили эквивалентен.
Касперд
Я также заметил ошибку в вашем редактировании. В одном месте вы написали включен, где вы должны были написать отключен.
Касперд
@kasperd Да, я просто перечитывал страницу POSIX, когда тоже это заметил. Уже исправлено. Дайте мне знать, если что-то еще нужно редактировать. Спасибо :)
Сергей Колодяжный
3

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

Роберт Лонгсон
источник
0

&это возвращает управление сценарием операционной системе, но отправляет ответ в фоновый режим, а не nohupнапрямую отправляет все выполнение

Bryro
источник