Как я могу отсоединить процесс от bash-скрипта?

18

Я пытаюсь отсоединить процесс от сценария bash, чтобы SIGINT не переадресовывался процессу при выходе из сценария.

Я использовал disownкоманду в терминале напрямую, однако в bash disownне останавливает пересылку SIGINT. Цель этого скрипта - запустить openocd, а затем gdb за один вызов. Поскольку скрипт никогда не завершается (он запускает gdb), SIGINT по-прежнему пересылается из gdb в openocd, что является проблемой, поскольку SIGINT используется в качестве команды остановки в gdb.

В терминале это будет выглядеть примерно так:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

когда вызывается на терминале в этом порядке, SIGINT не передается из gdb в openocd. Однако, если этот же вызов был в скрипте bash, SIGINT передается.

Любая помощь будет принята с благодарностью.

ps эта проблема в OS X, но я пытаюсь использовать инструменты, которые также переносимы на все инструменты Unix.

user2328113
источник
nohupне совсем правильный ответ. Вы должны добавить псевдокод или пример кода, чтобы показать более точно, что вы хотите.
Брюс Эдигер
1
Вы открыты для использования такого инструмента, как screen?
Эрик Ренуф,

Ответы:

16

Чтобы отсоединить процесс от bash-скрипта:

nohup ./process &

Если вы остановите свой bash-скрипт SIGINTнажатием (ctrl + c) или оболочка прекратит отправку, SIGHUPнапример, процесс не будет обеспокоен и продолжит нормальное выполнение. stdoutИ stderrбудет перенаправлен в файл журнала: nohup.out.

Если вы хотите выполнить отдельную команду, когда можете видеть вывод в терминале, используйте tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
Марк
источник
Почему это nohupнеобходимо? В чем разница, nohup COMMAND &и COMMAND &если ваша цель только запустить команду в фоновом режиме и освободить терминал?
Джеймс Вежба
@JamesWierzba Одно из отличий состоит в том, что если вам нужна команда для продолжения работы даже после выхода из оболочки, то nohup - это путь. В сети тысячи обширных объяснений. Например stackoverflow.com/questions/15595374/...
Марк
10

Для меня это прекрасно работает с отречением

command & disown
ManuelSchneid3r
источник
4

Решение, которое я нашел, включает в себя программу под названием «detach», написанную Анноном Инглорионом и загружаемую с его сайта.

После компиляции его можно использовать в сценарии следующим образом:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

Эта первая строка создает новый процесс (работает openocd) и сохраняет идентификатор процесса в файле (debug.pid) для последующего использования. Это предотвращает проблемы с подстановкой для pid, как указано в ответе Оливера. При выходе из следующей программы блокировки (gdb) файл, в котором хранится pid, используется для непосредственного уничтожения отдельного процесса.

user2328113
источник
Могу подтвердить, detachтворит чудеса.
AS
2

простое и портативное решение:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

Некоторые оговорки переносимости: psварианты зависят от ОС! вы могли бы вместо того, чтобы использовать вариант: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. atне может быть доступно (странно, но это случается ...). $(...)нужна не очень старая оболочка, в противном случае используйте backticks.

Оливье Дюлак
источник
Это кажется опасным, если поиск по pid может сделать неожиданные вещи, если более одного процесса запущено с тем же именем, или даже если другой процесс содержит слово openocd.
Орион
1
@orion: я привожу простой пример, чтобы дать идеи, о которых вы упоминаете, от которых легко избавиться: atзапустите скрипт, который запускает программу и вместо этого выдает ее pid в файле, и заставьте главный скрипт ждать этого файл, чтобы появиться и затем прочитать pid из него.
Оливье Дюлак
конечно, вы должны заменить в моем (слишком простом) примере grep тестом внутри awk, в правом столбце (обычно 8 долларов) (столбцы зависят от вашей ОС и версии / параметров ps)
Olivier Dulac