web-dev-qa-db-ja.com

シェルの終了時に死なないプロセスをフォークするにはどうすればよいですか?

シェルからemacsを実行する場合:

$ emacs foo &

そして、そのシェルを殺すと、emacsは死にます。

シェルが死んだときにコマンドが死なないようにするにはどうすればよいですか?

私はノーフへの言及を見つけましたが、それは役に立たないようです:

$ Nohup emacs foo &

シェルが死ぬと、まだemacsを殺します。

32
sligocki

これがXアプリとして実行されているのか、コンソールアプリとして実行されているのかについては言及していません。

コンソールアプリの場合は、もちろん閉じる必要があります。あなたはそれの入出力を取り除きました、より技術的にはそれがあった(疑似)ttyです。これがあなたの意図したことである可能性は非常に低いので、Xアプリについて話していると仮定しましょう。

Nohupは動作するはずですが、動作しない理由はわかりません。シェルが閉じると、シェルはプロセスグループ内のすべてのプロセスにSIGHUPを送信します。 nohupは、SIGHUPを無視するようにコマンドに指示します。

また、プロセスをプロセスグループから切断するsetsidを試すこともできます。

alias emacs='setsid emacs'

または、&の後にdisownを追加します

15
Rich Homolka

最も信頼できる方法は次のようです。

_(setsid emacs &)
_

これは_( &)_を使用してバックグラウンドに分岐し、setsidを使用して制御ttyから切り離します。

これをシェル関数に入れることができます:

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

fork emacs
_

可能性は次のとおりです。

  • disown組み込みコマンド:

    _emacs &
    disown $!
    _

    _&_はコマンドセパレーターとして機能し、disownはデフォルトで最新のジョブに設定されるため、これは以下のように短縮できます。

    _emacs & disown
    _
  • ダブル-fork()

    _(emacs &)
    _

    括弧_(_ _)_内のコマンドは、別のシェルプロセスで実行されます。

  • リッチが提案するsetsidは、新しい session を作成してプロセスの制御TTYの設定を解除するため、最良の選択である可能性があります。

    _setsid emacs
    _

    ただし、これは少し予測不可能でもあります。プロセスグループのリーダーである場合、バックグラウンドでのみfork()になります(setsidshスクリプトなど。このような場合、Ctrl-Cに耐性を持つだけです。)

42
user1686

シェル設定を確認してください。 Nohupの代わりに screen を試すこともできます。

5
Josh K