Фоновые задания в сценариях оболочки

421
Glyph

У меня есть сценарий оболочки script.shс командой, cmdзапущенной в фоновом режиме, то есть:

#!/bin/bash … cmd & … 

Если я открою эмулятор терминала (я пробовал xfce4-терминал и gnome-терминал) и запускаю script.shвнутри, моя команда cmdэффективно выполняется и выполняется в фоновом режиме, как и ожидалось.

Но, если я открою эмулятор терминала из предыдущего (или в начале моего сеанса рабочего стола, который является моим реальным вариантом использования), и выполню мой сценарий

xfce4-terminal -H -x script.sh (or gnome-terminal -x script.sh) 

команда cmdбольше не выполняется.

Я обнаружил, что могу заставить его исполниться, вставив set -mсвой сценарий, но я не понимаю, почему это необходимо (или на самом деле недостаточно) в этом случае, а не в предыдущем. Действительно, если я добавлю set -oв свой скрипт, я получу одинаковый вывод в обоих случаях.

Может кто-нибудь объяснить мне это и / или сказать, как правильно выполнять фоновые задания в сценариях оболочки? Спасибо!


РЕДАКТИРОВАТЬ: На самом деле, cmdвыполняется в обоих случаях, но во втором, он сразу же убит прекращением script.sh. Чтобы предотвратить это, можно использовать nohup, но этого недостаточно, и это самое странное для меня: нужно также добавить sleep 1или что-то в этом роде, чтобы позволить процессу правильно запускаться в фоновом режиме и отделяться от родительской оболочки, в противном случае это также убито.

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

0
Как вы уверены, что `cmd` не выполняется? Он легко и однозначно обнаруживается в выводе ps (и длится достаточно долго, чтобы его найти), или он издает звук или другую индикацию GUI? Xen2050 6 лет назад 0
@ Xen2050 Обычно я выбираю для `cmd` то, что можно увидеть в диспетчере задач, например` sleep n` с достаточно большим `n`. Но можно выбрать что-то с графическим интерфейсом, например `firefox` или что-то еще. Glyph 6 лет назад 0

2 ответа на вопрос

1
Tomasz Jakub Rup

Если вы открываете xfce4-trminalили gnome-terminal(или другой терминал) ваша оболочка в интерактивном режиме. Каждый скрипт запускается в интерактивном режиме.

Если Вы бежите script.shчерез

xfce4-terminal -H -x script.sh 

или же

gnome-terminal -x script.sh 

или другой терминал, ваша оболочка находится в неинтерактивном режиме.

Скрипты могут быть принудительно запущены в интерактивном режиме с -iопцией или с #!/bin/bash -iзаголовком. Имейте в виду, что это может привести к нестабильному поведению сценария или отображать сообщения об ошибках, даже если ошибок нет.

Что такое set -m? Это режим монитора . Фоновые процессы выполняются в отдельной группе процессов, и после их завершения печатается строка, содержащая их статус выхода. Он включен по умолчанию для интерактивных оболочек.

Что такое set -o? Это записать текущие настройки параметров в стандартный вывод в неопределенном формате.

Почему set -oработает?

Опция -o была принята из KornShell для удовлетворения потребностей пользователей. В дополнение к общепринятому дружественному интерфейсу, -o необходим для обеспечения режима редактирования командной строки vi, для которого историческая практика не выдает имя опции из одной буквы. (Хотя, возможно, было возможно изобрести такое письмо, было признано, что будут разработаны другие режимы редактирования, и -o предоставляет достаточно пространства имен для описания таких расширений.)

Исторические реализации несовместимы в формате, используемом для отчетов о состоянии опции -o. Формат + o без аргумента-опции был добавлен, чтобы обеспечить переносимый доступ к опциям, которые можно сохранить, а затем восстановить, используя, например, точечный скрипт.

Во всяком случае, set -mэто предпочтительный способ.

Нет ... оболочка в вашем терминале является интерактивной, а та, которая вызывается для запуска сценария, - нет. Это то, что я наблюдаю, в частности, помещая `set -o` в мой скрипт: в обоих случаях его вывод одинаков, особенно в отношении режима монитора, который отключен (по умолчанию в неинтерактивном режиме). Я не помещаю `set -o`, чтобы увидеть, работает ли он, а чтобы увидеть его вывод. Glyph 6 лет назад 0
0
Glyph

Ответ на вопрос дан на Unix Stackexchange (см. Также дополнительные комментарии ниже ответа). Вопрос в том, кто посылает сигнал SIGHUP, кому и когда. И альтернатива set -m / set +mвокруг cmd &в script.shтом trap '' HUP / trap - HUP.

Похожие вопросы