web-dev-qa-db-ja.com

プログラムをデーモンとして実行することと、「&」でバックグラウンドにフォークすることの違いは何ですか?

UNIXベースのシステムにサービスをデプロイする場合、sysadminの観点からの実際的な違いは何ですか?

46
user1561108

デーモン化の従来の方法は次のとおりです。

fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()

これにより、プロセスがターミナルと同じプロセスグループに含まれなくなり、プロセスと一緒に強制終了されることがなくなります。 IOリダイレクトは、出力が端末に表示されないようにすることです。

30

デーモンの場合、何にも関係のないプロセスが必要です。少なくとも、それを独自のセッションにして、端末に接続せず、親から継承されたファイル記述子を開いたり、親を気にかけたりしないでください(init以外)現在のumountを妨げないように_/_のディレクトリ...

端末から切り離すには、新しいセッションを作成しますが、セッションを作成するには、グループ(またはセッション)のリーダーであってはならないため、新しいプロセスを分岐することが最善です。親が存在すると仮定すると、プロセスは親を持たなくなり、initによって採用されます。次に、すべての可能なファイル記述子を閉じます。chdir("/")(現在の作業ディレクトリを閉じることはできませんcloseため、次のようにそのリソースを解放しますファイル記述子。少なくとも_/_を現在の作業ディレクトリにしても、ディレクトリのマウント解除はできません)。

そのプロセスはセッションリーダーであるため、端末デバイスを開くと、その端末の制御プロセスになるリスクがあります。二度目のフォークはそれが起こらないことを保証します。

一方、&は、対話型シェルでは新しいプロセスグループをフォークして作成し(端末のフォアグラウンドプロセスグループに含まれないようにするため)、非対話型シェルではプロセスをフォークしてSIGINTを無視します。端末からデタッチせず、ファイル記述子を閉じません(一部のシェルはstdinを_/dev/null_に再度開きます)...

35

プログラム/プロセスをデーモンとして実行することと、アンパサンドを使用してバックグラウンドにフォークすることの違いは、基本的に所有権に関連しています。

ほとんどの場合、デーモンの親プロセスはinitプロセス(UNIXシステムで開始される最初のプロセス)であり、そのプロセスの子であるデーモンは、それが直接の非特権ユーザーとして制御します。一方、プログラム/プロセスをバックグラウンドにフォークすると、いつでもフォアグラウンドにコールバックしたり、強制終了したりできます。

9
Odaym

command &を使用すると、親が死亡すると、SIGHUPシグナルによってプロセスが強制終了されます。

ただし、システム管理者はいくつかの回避策にアクセスできます。

Bashシステムでは、以下を使用できます。

(trap '' HUP; command) &

これはサブシェルを開き、HUPシグナルを空のハンドラーでトラップし、アンパサンド/フォークします。

出力は引き続き間違ったttyにリダイレクトされる可能性があります。または迷子になる。
&>command.out1>output.out、または2>errors.outで修正できます

また、ほとんどのシステムでは、Nohupコマンドにアクセスできます。
Nohupは、このプロセスを大幅に簡略化します。かなり標準的ですが、多くのbusyboxが埋め込まれていることがわかりましたARMディストリビューションには欠落しています。

Nohup command &

..これで完了です。出力はIIRCからNohup.outにリダイレクトされますが、このファイル名はオプションで変更できます。

7
ZJR