シェルスクリプトをデーモンとして実行する「正しい」方法

シェルスクリプトをデーモンとして実行する「正しい」方法

文章を書いていますシェルスクリプト起動時にデーモンとして実行したいです。外部ツールは使用されません。デーモンツールまたは悪魔


Linuxデーモンの作成HOWTO

~によるとLinuxデーモンの作成HOWTO、ㅏ適切デーモンプロセスには次の特徴があります。

  • フォーク親プロセスで
  • 閉鎖みんなファイル記述子(つまりstdin、、、、stdoutstderr
  • 開いている丸太書き込み用(設定されている場合)
  • 変更タスクリスト継続的(通常/
  • 初期化ファイルモードマスク(マスク)
  • ユニークな作りセッションID(セキュリティ識別番号)

悪魔紹介する

これ悪魔紹介するさらに一歩進んで、一般的なデーモンは次の点を指摘しています。

  • それとの関係を切る制御端子(存在する場合)すべてを無視します。端末信号
  • それとの関係を切るプロセスグループ
  • ハンドルSIGCLD

一般的なLinuxツールのみを使用して、またはshスクリプトでdashこれらすべての操作をどのように実行できますか?bash

スクリプトは、追加のソフトウェアなしでできるだけ多くのディストリビューションで実行できる必要があります。ダーバン私たちの主な焦点です。


メモ:オンラインに多くの答えがあることを知っています。スタック交換nohupネットワークでは、または使用をお勧めしsetsidますが、これらの方法のいずれも上記の要件をすべて満たすことはできません。


編集する:これDaemon(7) マンページSysV古いスタイルデーモンと新しいスタイルsystemdデーモンとの間にわずかな違いがあるように見えますが、いくつかのガイドラインもあります。さまざまなディストリビューションとの互換性が重要であるため、回答の違いを明確に説明する必要があります。


答え1

使用システム単純なユニットを作成してスクリプトをデーモンとして実行できる必要があります。いろいろあるオプション追加できますが、これは非常に簡単です。

スクリプトがあるとしましょう/usr/bin/mydaemon

#!/bin/sh

while true; do
  date;
  sleep 60;
done

忘れないでくださいsudo chmod +x /usr/bin/mydaemon

単位を作成します/etc/systemd/system/mydaemon.service

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

デーモンプロセス実行開始

systemctl start mydaemon.service 

起動時に起動するには有効にしてください。

systemctl enable mydaemon.service

もしsystemdベースのシステム(今日のほとんどのLinuxディストリビューションの場合と同様)では、これは実際には外部ツールではありません。欠点は、どこでも動作しないことです。

答え2

おそらくここに何かが落ちたでしょう。なぜ合わないのですnohupか?もちろん十分ではありませんホロしかし、サプリメントは簡単に見えます。

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

私が知っている限り:

  • 出力は適切にリダイレクトされます(必要に応じて/ dev / nullを使用)。
  • umaskは継承されます
  • stdinとにかく親スクリプトが終わると死にます。
  • daemon.shスクリプトの親はinit(またはsystemd)にリセットされます。

はっきりしたものを見逃しているという強い感じを受けました。反対票をもらったのですが、何か教えてください:-)

答え3

ほとんどのディストリビューションには、シェルスクリプトを守るためのLinuxscreenコマンドが含まれています。私はそれを頻繁に使用します。以下は、分割画面セッションを開始、一覧表示、および終了する簡単な例です。

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit

関連情報