Ответы:
Трейлинг- &
оператор в конце команды используется для перевода команд в фоновый режим. На самом деле это стандартный синтаксис, определенный стандартом 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 |. Это неявное перенаправление стандартной ошибки на стандартный вывод выполняется после любых перенаправлений, указанных в команде.
Это означает запустить команду в фоновом режиме. Вызывающий сценарий продолжается, а не блокируется до завершения вызываемой команды.
&
сокрытии вывода, звучит неправильно. Абзац из стандарта, который вы цитируете, говорит о вводе , а не выводе . Причина различия между включением или отключением управления заданиями заключается в том, что фоновый процесс, пытающийся прочитать данные с tty, будет приостановлен. В этот момент вам нужно использовать управление заданиями, чтобы поместить его на передний план, чтобы обеспечить ожидаемый ввод. Все это не может быть выполнено без контроля заданий, и поэтому, если контроль заданий отключен, стандартный ввод должен быть перенаправлен/dev/null
или эквивалентен.