Как мне развить процесс, который не умирает при выходе из оболочки?

31

Если я запускаю emacs из оболочки:

$ emacs foo &

а затем убить эту оболочку, Emacs умирает.

Как я могу выполнить команду, чтобы она не умерла при смерти оболочки?

Я нашел ссылки на nohup, но это, похоже, не помогает:

$ nohup emacs foo &

все еще убивает Emacs, когда оболочка умирает.

sligocki
источник

Ответы:

13

Вы не упоминаете, работает ли это как приложение X или консольное приложение.

Если это как консольное приложение, конечно, его нужно закрыть. Вы избавились от его ввода / вывода, более технически (псевдо) tty он был включен. Маловероятно, что вы это имели в виду, поэтому давайте предположим, что вы говорите о приложении X.

nohupдолжно работать, не уверен, почему это не так. Когда оболочка закрывается, она отправляет SIGHUPвсем процессам в своей группе процессов. nohup говорит команде игнорировать SIGHUP.

Вы также можете попробовать setsid, который отключает процесс от группы процессов

alias emacs='setsid emacs'

Или добавить disownпосле&

Рич Гомолка
источник
Ах, отличный сетсид работает. Извините, что не ясно. Да, я имею в виду приложения X, которые на самом деле не работают в оболочке. По сути, я хочу запустить emacs (или любой другой процесс) из оболочки, но я не хочу, чтобы он каким-либо образом был связан с оболочкой. Я просто начинаю это там для удобства.
Sligocki
41

Наиболее надежным методом является:

(setsid emacs &)

Это используется ( &)для разветвления на задний план и setsidотсоединения от управляющего tty.

Вы можете поместить это в функцию оболочки:

fork() { (setsid "$@" &); }

fork emacs

Возможности:

  • disownКоманда встроенная:

    emacs &
    disown $!
    

    &действует как разделитель команд и по disownумолчанию будет соответствовать самой последней работе, поэтому ее можно сократить до:

    emacs & disown
    
  • Double- fork():

    (emacs &)
    

    Команды в скобках ( )выполняются в отдельном процессе оболочки.

  • setsidкак предложил Rich, может быть лучшим выбором, потому что он отменяет управляющий TTY процесса, создавая новый сеанс :

    setsid emacs
    

    Тем не менее, это также немного непредсказуемо - это будет только fork()фон, если он является лидером группы процессов (что не произойдет, если , например, setsidиспользуется в shскрипте; в таких случаях он просто станет устойчивым к Ctrl- C.)

grawity
источник
Большой! все это работает для меня. Приятно иметь еще несколько инструментов в моем арсенале.
Sligocki
Хм ... будет (exec emacs)работать?
Hello71
@ Привет: Это не будет отличаться от всего (emacs). Если подоболочке дается одна команда, execподразумевается, по крайней мере, в случае bash. То же самое относится к bash -c 'foo'против bash -c 'exec foo'. (Однако обратите внимание, что сам emacs может отсоединяться от терминала; например, это делает gvim. Лучше тестировать с помощью программы с известным поведением.)
grawity
Отлично учиться технике двойных вилок; Благодарность!
Дейв Абрахамс,
Нашел это во время троллинга, чтобы решить мою проблему. (Сетид Emacs &) работал для меня. Спасибо за хорошо написанный ответ.
Полб
5

Проверьте настройки оболочки. Вы также можете попробовать экран вместо nohup.

Джош К
источник
Экран позволяет вам вернуться к процессу позже, screen -rесли вы используете его Ctrl-A Ctrl-Dдля отключения перед выходом из системы.
Broam
Это очень хороший момент. Мне нужно было обратное, то есть разветвление подоболочки и выполнение других задач, не дожидаясь ее завершения, но screen -d -m sh -c "{do stuff } exit"имеет гораздо больше смысла.
Немо