Как демонтировать shell-скрипт во FreeBSD (и macOS) - PullRequest
1 голос
/ 30 апреля 2020

Обычно я запускаю долго работающий скрипт оболочки:

% (nohup ./script.sh </dev/null >script.log 2>&1 & )

Перенаправления закрывают stdin и открывают stdout и stderr; nohup останавливает HUP, достигающий процесса при выходе из процесса владения (я понимаю, что 2>&1 несколько избыточен, так как nohup делает что-то подобное в любом случае); а фоном в подоболочке является двойная вилка, которая означает, что родительский процесс ./script.sh завершился, пока он еще работает, поэтому он получает процесс init в качестве родительского.

Это не полностью работа, однако, потому что, когда я выхожу из оболочки, из которой я это вызывал (обычно, конечно, я делаю это на удаленной машине), она не выходит чисто. Я могу сделать ^C для выхода, и это нормально - процесс продолжается в фоновом режиме, как и предполагалось. Однако я не могу понять, что / не происходит, требует ^C, и это меня раздражает.

Вышеуказанные действия, кажется, отмечают большинство полей в unix FAQ (вопрос 1.7), за исключением , что я ничего не делаю, чтобы отсоединить этот процесс от управляющего терминала или сделать его лидером сеанса. Вызов setsid (2) существует во FreeBSD, но отсутствует команда setsid; и, насколько я понимаю, нет очевидной замены этой команде. Конечно, то же самое верно и для macOS.

Итак, вопросы:

  • Есть ли на этой платформе абонент с другим именем setsid, что я отсутствует?
  • Что именно происходит, когда я выхожу из вызывающей оболочки, которую я убиваю с помощью ^C? Может ли это как-то меня укусить?

Похожие вопросы (например, 1 , 2 ) либо отвечают на несколько другой вопрос, либо предполагают наличие команда setsid.

(Этот вопрос раздражал меня годами, но поскольку то, что я здесь делаю, на самом деле не работает, я никогда прежде не удосужился заняться расследованиями, получить тупик и спросить о это).

1 Ответ

1 голос
/ 02 мая 2020

В FreeBSD из коробки вы можете использовать daemon -- run detached from the controlling terminal. опция -r может быть полезна:

-r       Supervise and restart the program after a one-second delay if it
         has been terminated.

Вы также можете попробовать супервизор, например immortal доступен для обеих платформ:

pkg install immortal  # FreeBSD
brew install immortal # macOS

Демонизировать ваш сценарий и журнал (stdout/stderr), которые вы можете использовать:

immortal /path/to/your/script.sh -l /tmp/script.log

Или для дополнительных параметров вы можете создать my-service.yml, например:

cmd: /path/to/script
cwd: /your/path
env:
    DEBUG: 1
    ENVIROMENT: production 
log:
    file: /tmp/app.log
stderr:
    file: /tmp/app-error.log

И затем запустить его с immortal -c my-service.yml

Дополнительные примеры можно найти здесь: https://immortal.run/post/examples

Если вы просто хотите использовать nohup и сохранить stdout & stderr в файл, вы можете добавить это в ваш скрипт:

#!/bin/sh
exec 2>&1

...

Узнайте больше о exec 2>&1 в этих ответах { ссылка }

И затем просто позвоните nohup /your/script.sh & и проверьте файл nohup.out, от man

FILES
       nohup.out   The output file of the nohup execution if stan-
                   dard  output  is  a terminal and if the current
                   directory is writable.

       $HOME/nohup.out The output file of the nohup execution if stan-
                   dard  output  is  a terminal and if the current
                   directory is not writable.
...