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


20

daemontoolsdaemonizeなどの外部ツールを使用せずに、起動時にデーモンとして実行したいシェルスクリプトを書いています。


Linux Daemon Writing HOWTO

Linux Daemon Writing HOWTOによると、適切なデーモンには次の特性があります。

  • 親プロセスからの分岐
  • クローズすべてのファイル記述子を(すなわち、stdinstdoutstderr
  • 書き込み用のログを開きます(設定されている場合)
  • 作業ディレクトリを永続的なものに変更します(通常/
  • ファイルモードマスク(umask)をリセットします
  • 一意のセッションID(SID)を作成します

デーモン化入門

デーモン化導入はまた、典型的なデーモンを述べ、さらに行きます:

  • 制御端末(存在する場合)との関連付けを解除し、すべての端末信号を無視します
  • プロセスグループとの関連付けを解除します
  • ハンドル SIGCLD

どのように私はこのすべてを行うだろうshdashまたはbash唯一の共通のLinuxツールとスクリプト?

Debianは主な焦点ですが、スクリプトは追加のソフトウェアなしでできるだけ多くのディストリビューションで実行できるはずです。


注:またはの使用を推奨するStackExchangeネットワーク上の答えがたくさんあることは知っていますが、これらの方法はいずれも上記の要件のすべてに対応していません。nohupsetsid


EDIT:デーモン(7)のmanページには、古いスタイルのいくつかの違いがあるように見えるが、また、いくつかのポインタを与えるSysVデーモンと新しいsystemdもの。さまざまなディストリビューションとの互換性が重要なので、答えが違いを明確にするようにしてください。



1
独自のシェルスクリプトを作るための「正しい」方法は、それはそれ自身のログを間に合わせるなど、デーモン、としてそれを起動するための方法を提供することにあるようなものdaemon、それらの他のもので実行するためのもので、任意として実行するための規定でシェルスクリプトをデーモン。あなたは著者であり、そのスクリプトの記述方法を完全に制御しているので、systemd unitfileまたはrc.dスクリプトから起動できるようにします。あなたはなかった「適切」を指定します!
リッチ

回答:


16

systemdを使用すると、単純なユニットを作成して、スクリプトをデーモンとして実行できるはずです。追加できるオプションはたくさんありますが、これはあなたが得ることができるのと同じくらい簡単です。

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

#!/bin/sh

while true; do
  date;
  sleep 60;
done

ユニットを作成します/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

場合は Linuxディストリビューションの大半が今日あるsystemdに基づいて、システム上、これは本当に外部のツールではありません。マイナスは、どこでも機能しないことです。


3
私はsystemdアプローチが好きですが、OPは「外部ツールなし」と言いました。Linuxディストリビューションには、systemdがまだない、またはsystemdとOpenRCなどの他の何かを選択できるディストリビューションがあります。
クリスティアンシウピトゥ

5
systemdを使用するディストリビューションでsystemdは、「外部ツール」にすぎませんbash
アレクサンダー

7

おそらくここに何かが欠けています。なぜ正確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

私は明らかなことを見逃していると強く感じています。Downvote、しかしそれが何であるか教えてください:-)


2
非常によく似たものを提案しようとしていました。で使用nohup&、I / Oリダイレクトを使用して、いくつかの非Cデーモンユーティリティを起動します。おそらく、nohupコマンドをa でラップしてsu -c "nohup ... &" -s /bin/bash systemUser、非特権ユーザーとしてデーモンを実行するセキュリティを追加します。
111 ---

4

screenほとんどのディストリビューションに含まれるLinux コマンドは、シェルスクリプトをデーモン化できます。よく使います。デタッチスクリーンセッションを開始、一覧表示、および終了する簡単な例を次に示します...

# 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

2
screenシェルスクリプトのデモを行いません。単にそれらを別のターミナルで実行し、セッションを終了せずにこのターミナルからデタッチできます(PCからキーボードを取り外すなど)。したがって、切り離されたターミナルで実行されているプログラムはバックグラウンドで実行されています。したがって-バックグラウンドでパスプログラムを切り離します。
ユーリゴンチャルク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.