web-dev-qa-db-ja.com

start-stop-daemonと&で実行することの違いは何ですか?

/etc/init.dにサービスを設定しています。私はそこでさまざまなスクリプトを見ています。いくつかはstart-stop-daemon ...で実装され、一部は/path/to/script &で実装されています。

それらのすべてはpidをファイルに保存し、いくつかのチェックを行います。

ベストプラクティスは何ですか、違いは何ですか、ここで知っておくべき重要なことは何ですか? (一般に)

私の特定のケースでは、Javaにアプリケーションが1時間に1回程度呼び出す単純な軽量のlocalhost httpサーバーがあり、それは愚かな乱数を与えるだけです(詳細はここではありませんが、これが私の質問で問題になった場合に備えて、ファイルシステムやスレッドなどの複雑なものは使用しません)

ありがとう

18
Thomas

バックグラウンドジョブ(つまり、&で開始)には、それが開始された端末に接続されているstdin、stdout、およびstderrが残っています。突然、端末に(たとえば、エラーメッセージ)を書き込む(フォアグラウンド)またはキーボードからの入力を待機して一時停止します(最初にフォアグラウンドに置く必要があります)。もちろん、stdoutとstderrをファイルまたは/ dev/nullにリダイレクトして、バックグラウンドジョブが端末に書き込まれないようにすることができます。

バックグラウンドジョブもフォアグラウンドに配置できます。現在のフォアグラウンドジョブが停止し、fg(フォアグラウンド)コマンドを使用して、バックグラウンドジョブをフォアグラウンドに配置します。端末からの信号によって、バックグラウンドジョブに到達することもできます。端末を閉じるときにSIGHUPを押すと、通常は端末で開始された(ほとんどの)プログラムが終了します。

デーモン-init.dによって自動的に開始されるデーモンのようですが、ターミナルから手動で開始することもできます-一方、すべてのターミナルから切断されて実行されます。端末から手動で開始した場合でも、デーモンは端末から切断されるため、デーモンは書き込み(stdout、stderr)も読み取り(stdin)もできません。端末から「自動的に」送信される信号に対しても「免疫」です。 (ただし、kill -signal pid)。

「バックグラウンド」と「フォアグラウンド」は、現在ターミナルを制御しているプロセスであるかどうかに関係なく、何らかのターミナルに対するプロセスのステータスを指します。デーモンはターミナルに接続されていない(しかし、あらゆる方法でターミナルから大幅に切断されている)ため、バックグラウンドで実行されているとは言えません。デーモンは、ターミナルに関連付けられずに実行されている単なるプロセスであり、フォアグラウンドでもバックグラウンドでもありません。

プロセスが使用する端末を示すオプションを指定してpsを使用すると、フォアジョブとバックグラウンドジョブの両方が端末(例:tty2)に関連付けられていることがわかります。一方、デーモンには「?」があります。この分野で。

デーモンは、手動で開始された場合でも、通常はそのように動作します。あなた自身のデーモンを作成することはかなりの作業です-それをターミナルから完全に切断するために含まれるいくつかのトリックがあります。実行する独自のユーザー/グループを作成する必要があります。ファイルを作成する場合は、通常/ tmp、/ var/tmp、または/ var/runを使用する必要があります。通常、他の場所に権限を付与することはできません。端末にエラーを報告できないため、ログファイルに書き込む必要があります(たとえば、/ var/log内の独自のログファイル)。デーモンは/ var/runに現在のPIDでエントリを作成し、別のインスタンスがすでに実行されているかどうかを確認する必要があります。該当する場合、ファイルまたはデバイスのロック(/ var/lock)を尊重する必要があります。それはそれの設定ファイルをリロードしてSIGHUPに応答し、更新された設定を使用する必要があります。

別のポイントは、ほとんどのデーモンがどのように機能するかです。デーモンは通常、2つの異なるモードのいずれかで実行できる単一の実行可能ファイルです。それが元のデーモン(親)であるかどうかに応じて、起動時または手動で開始されます...またはこの親によって生成された子です。親プロセスは通常、特定の時間、経過した時間、特定のネットワークポートへの接続の試みなど、何らかのイベントを待機します。これが発生すると、親は(fork()システムコールを使用して)自身と同じ子プロセスを作成し、すぐに別のイベントの待機に(そしてさらに子を生成することにも)戻ります。ディスクの同期、コマンドの実行(cronなど)、またはネットワーク接続の確立(sshdまたはftpdなど)を実際に行うのは子プロセスです。 )。親と子の唯一の違いは、それらが異なるPIDを取得し、子のPPID(親PID)が親プロセスのPIDであることです。これは、プロセスが親か子かを判断するために使用できます。したがって、同じプロセスが、待機(およびスポーン)親として、または作業子として、2つのモードで動作できる必要があります。

デーモンを書くのは難しくありませんが、それも簡単なことではありません。最初に知っておく必要のある「トリック」がかなりあることがわかります。一般に、デーモンを作成するには、他の代替手段と比較してわずかな利益で多くの労力が必要になると思います。

バックグラウンドジョブでNohupまたはdisownを使用することは、ターミナルが閉じてもプロセスを存続させることができるため、通常はこれで十分です。 stdoutとstderrをファイルまたは/ dev/nullにリダイレクトすることをお勧めします。よりインタラクティブなプログラムの場合、screenは、何かが必要になるまで「片付ける」ための良い方法です。 atbatchcrontabも検討に値します。

27
Baard Kopperud