Разница между запуском фонового процесса в BASHRC и командной строке - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь установить фоновый процесс автоматически.

nohup program > /tmp/program.log 2>&1 < /dev/null &
disown

Если я проверяю, запущен ли процесс, и запускаю его при входе в систему через ".bashrc", программа запускается, но затем Умирает при выходе.

НО, если я делаю точно такую ​​же команду в командной строке, программа продолжает работать в фоновом режиме, когда я выхожу.

Я не могу найти никакой разницы в программной среде междуначало bashrc и начало кли(Bashrc почти ничего не имеет).Мое понимание программы в обоих случаях должно рассматриваться одинаково.

В чем разница, и как я могу остановить уничтожение запущенного 'демона' bashrc при выходе из оболочки.

PS:удаление nohup не имеет значения.и я наблюдал, как работающая программа затем умирала от отдельного входа в систему, когда исходный вход в систему выходил.

И до того, как кто-то что-то скажет ... Добавление «disown» после фоновой обработки программы в bashrc НЕ исправило это!

ОБНОВЛЕНИЕ: Если соединение входа в систему ssh прервано (окно закрыто или соединение внезапно прервано), программа, запущенная в bashrc, продолжает работать, но это происходит потому, что запущенный bash также все еще работает (вхотя бы пока).Фон удаляется только в том случае, если для bash вы набираете «exit», или bash уничтожается (даже при необратимом сигнале 9!).

PPID программы (отрицаемой оболочкой) равен 0, чтоего родитель не является оболочкой или процессом инициализации!Это случай, независимо от того, как он запускается.

ОБНОВЛЕНИЕ 2 ... фоновая программа запущена из bashrc ...

# ps -jA w
   PID   PGID    SID TTY      STAT   TIME COMMAND
   891    891    891 pts/2    Ss+    0:00 /bin/bash
   899    891    891 pts/2    Sl+    0:00 program

Я убил его, затем запустил его из командной строки ...

   891    891    891 pts/2    Ss+    0:00 /bin/bash
   958    955    891 pts/2    Sl     0:00 program

Теперь, когда оболочка существует, программа не завершается.Таким образом, похоже, единственное отличие - это изменение PGID.

Как запустить процесс с другим PGID?

Ответы [ 3 ]

2 голосов
/ 01 июля 2019

Группы процессов необходимы для управления заданиями, потому что оболочке нужно что-то для отправки сигналов управления заданиями, например, когда вы набираете fg.POSIX.1-2017 состояния

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

(курсив мой) Это, кажется, даже приравнивает понятия «группа процессов» и «работа», хотя большинство людей используют термин«задание» для групп процессов (и даже дочерних элементов в собственной группе процессов оболочки), которые зарегистрированы в оболочке таблица заданий (и могут быть удалены из этой таблицы встроенным disown)

Таким образом, если оболочка не хочет запускать дочернюю команду (или даже конвейер оболочки) под управлением заданием, она не создает новую группу процессов (путем вызова setpgrp())

Это происходитнапример, при использовании подстановки процесса

blah=$(sleep 1000 | sleep 1000)

(попробуйте и посмотрите на вывод ps -jA w!) и, по-видимому, при запуске команд с .bashrc

nohup <command> по своемуelf, не запускает новую группу процессов, она только игнорирует SIGHUP и затем запускает command

Linux (и другие ОС, когда вы устанавливаете что-то вроде util-linux)имеет команду setsid , которая будет делать то, что вы ожидали (но не получили) из nohup: setsid command будет создавать новую группу процессов для <command> и сделайте его лидером нового сеанса.PGID этой новой группы процессов будет неизвестен вызывающей стороне (bash в данном случае), поэтому нам больше не нужно использовать nohup.

Итак, используйте setsid вместоnohup и все готово (я только сейчас вижу комментарий Марка Плотника, который касается денег. О, хорошо, я надеюсь, что мой ответ также проясняет причину , почему setsid является лучшей альтернативой вэто дело)

0 голосов
/ 01 июля 2019

Хорошо ... кажется, что проблема была вызвана окружающей средой.

Оболочка запускалась в док-контейнере. и похоже, что Docker Exec завершает все процессы в одной и той же группе процессов, а не в оболочке. Или, по крайней мере, так оно и есть.

Однако я все еще нахожу странным, что программа, основанная на ".bashrc", наследует ту же группу процессов, что и родительская оболочка, НО точно такая же команда фонового режима из командной строки получает свою собственную отдельную группу процессов.

Как только я обнаружил, что это было причиной, я обнаружил, что группы процессов упоминались в справочной странице BASH, что касается Фонового процесса, хотя в нем не упоминается разница, запускающая его в «.bashrc» и CLI.

0 голосов
/ 25 июня 2019

Каждый процесс bash имеет PPID (родительский PID)

Если вы запустили из терминала следующее:

nohup tail -f /dev/null > /tmp/rand.txt &

PPID с выхода ps -ef показывает, что PPID является init (Первый процесс запускается):

UID        PID  PPID  C STIME TTY          TIME CMD
user     18424     1  0 16:17 tty1     00:00:00 tail -f /dev/null

Если вы запускаете ту же команду из bashrc, PPID будет процессом bash:

UID        PID  PPID  C STIME TTY          TIME CMD
user     16405 16404  0 Jun20 tty2     00:00:08 bash
user     18424 18386  0 16:17 tty1     00:00:00 tail -f /dev/null

При запуске из терминала процесс будет продолжаться до тех пор, пока инициализация не будет остановлена.

При запуске из bashrc процесс будет продолжаться до тех пор, пока bash не будет остановлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...