start-stop-daemonによって開始されたプロセスのstdoutをログに記録するにはどうすればよいですか?


120

私はinitスクリプトを使用して、以下で始まる簡単なプロセスを実行しています。

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS

$ DAEMONと呼ばれるプロセスは通常、ログ情報を標準出力に出力します。私の知る限り、このデータはどこにも保存されていません。

$ DAEMONのstdoutをどこかのファイルに書き込むか、追加します。

私が知っている唯一の解決策は、$ DAEMONの代わりにシェルスクリプトを直接呼び出すようにstart-stop-daemonに指示することです。次に、スクリプトは$ DAEMONを呼び出し、ログファイルに書き込みます。しかし、これには、デーモン自体を変更するような、このような一般的なタスクを解決するための間違った方法と思われる追加のスクリプトが必要です。

回答:


127

ypocatの答えを拡張すると、コメントできないので、

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
 --make-pidfile --pidfile $PIDFILE --background       \
 --startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

を使用execしてデーモンを実行すると、stopは、bashの親だけでなく、子プロセスを正しく停止できます。

--startas代わりにを使用--execすると、プロセスがそのpidによって正しく検出され、startが複数回呼び出されても、デーモンの複数のインスタンスが誤って開始されることがなくなります。それ以外の場合、start-stop-daemonは/ bin / bashプロセスを探し、デーモンを実行している実際の子プロセスを無視します。


2
これは、@ ypocatのソリューションよりもはるかに優れたソリューションです。主に、置き換え--startてデーモンをシャットダウンしても、--stop実際に機能するためです。
2014年

このコマンドをinit.dではなくrc.localから実行してみました...同じ結果が得られないようです。ただし、SSHを介してシェルから実行すると、魅力的に機能します。
nemo 2014

1
付随するものはstart-stop-daemon --test (...)どのようになりますか?
Abdull 2016

2
@MattClimbs起動するたびにファイルを上書きします。追加の>>代わりに使用します>
Meow

2
ログが空だったために(私のように)気が狂う前に、これはバッファリングされていることに注意してください!"exec stdbuf -oL -eL $ DAEMON $ DAEMONARGS> $ LOGFILE 2>&1"を使用して、出力に各行を強制的にフラッシュさせることができます(blog.lanyonm.org/articles/2015/01/11/…から)
piers7

47

あなたがする必要があります:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

また、--chuidまたはを使用する場合--userは、ユーザーが/var/logまたは既存のに書き込みできることを確認して/var/log/some.logください。最善の方法は、そのユーザーに所有権を持たせること/var/log/subdir/です。


1
素晴らしい、ypocatに感謝します。今日、ログを保存するだけでなく、-execでは許可されていない非バイナリスクリプトを実行する必要がありましたが、あなたのトリックは回避できます!
joeytwiddle 2012年

8
マイナス面は...サービスを停止するとbashは終了しますが、子プロセスbashは開始しません!(私の場合、DAEMON = coffee)。
joeytwiddle

1
do_stopの先頭にあるbashプロセスのすべての子プロセスを強制終了することで、これを回避しました。 bashPID=$(cat $PIDFILE); [ -n "$bashPID" ] && pkill -P "$bashPID"
joeytwiddle

5
知っておくべきこと、そしてpkill解決策も。... -c "exec $DAEMON..."(「exec」を追加して)何をするのか疑問に思います。今、これをプレートに載せないでください。試してみることができません。
youurayy 2012年

12
@ypocat -c "exec $ DAEMON ..."で動作することを確認しました。つまり、pkillハックは必要ありません。
overthink

40

デーモンの出力のキャプチャーを--no-close開始start-stop-daemonするときに、パラメーターを使用できるようになっているようです。この新機能dpkg、Debianのバージョン1.16.5以降のパッケージで利用できます。

--backgroundでfdsを閉じることを無効にする新しい--no-closeオプションを追加します。

これにより、呼び出し元はデバッグのためにプロセスメッセージを表示したり、ファイル記述子をログファイルやsyslogなどにリダイレクトしたりできます。


8
Ubuntu 12.04では利用できないのは残念です:(
Leon Radley '25

--no-closeが機能しないようです...出力はまだシェルに
送られてい

+1デーモン化されたnode.jsサービスを使用して、Debian squeezeで完全に動作します。
講演者2014

2
@stantonk stdout / stderrもファイルにパイプしましたか?完全なコマンドラインは次のようになります。そして、ログファイルがユーザー$ USERによって書き込めることを確認してください:start-stop-daemon --start --chuid $ USER --pidfile $ PIDFILE --background --no-close --make-pidfile --exec $ DAEMON -$ DAEMONARGS >> /var/log/xxxxx.log 2>&1
nharrer 2014

1
これはopenrcでは利用できませんstart-stop-daemon。ただし、openrcバージョンには、stdoutとstderrをそれぞれリダイレクトする-1および-2オプションがあります。
リトルデュード2016

14

openrc(たとえば、gentooまたはalpine linuxのデフォルト)にstart-stop-daemonは、-1および-2オプションがあります。

-1、--stdout stdoutをファイルにリダイレクト

-2、--stderr stderrをファイルにリダイレクトします

だからあなたはただ書くことができます:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE

9

デーモンの出力をキャプチャしてファイルに保存することはそれほど難しくありません。

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas $DAEMON --no-close \
  -- $DAEMON_ARGS >> $LOGFILE 2>&1

ただし、このソリューションはでは最適ではない可能性がありますlogrotate

出力をsyslogにキャプチャする方がよい場合があります。上のDebianこれはsystemdにサービスの動作と一致します。次の簡単な上記の例を書き直そうとすると、デーモンだけが終了し、すべての子孫が終了するわけではないため、デーモンを停止した後、2つの親なし(「ゾンビ」)プロセス(ロガーとデーモン)が残るため、間違っていますstart-stop-daemon

## Do not use this!
start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /bin/sh \
  -- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""

これを機能させるには、SIGTERMからの受信時に子を終了するラッパーが必要start-stop-daemonです。幾つかある:

duende
start-stop-daemon --start --background \
  --pidfile $PIDFILE \
  --startas /usr/sbin/duende \
  -- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \
  /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""

注:uid=65534はユーザーnobodyです。

長所:機能し、比較的簡単です。
短所:4つのプロセス(スーパーバイザーduende、ドロップされた特権を持つそのフォーク(ロガー)、suおよびデーモン自体); 必須--chroot; デーモンがすぐに終了した場合(無効なコマンドなど)status_of_proc -p $PIDFILE "$DAEMON" "$NAME"正常に開始されたと報告します。

デーモン
start-stop-daemon --start --pidfile $PIDFILE \
  --startas /usr/bin/daemon \
  -- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \
  -- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""

長所:3つのプロセス(スーパーバイザーdaemonsuデーモン自体)。
短所:管理が難しく$PIDFILE混乱によるデーモンのコマンドラインオプションを、デーモンがすぐに終了した場合(無効なコマンドなど)status_of_proc -p $PIDFILE "$DAEMON" "$NAME"正常に開始されたと報告します。

pipexec勝者):

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /usr/bin/pipexec -- -k \
   -- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}'

長所:3つのプロセス(スーパーバイザーpipexecloggerデーモン自体)。デーモンがすぐに終了した場合(無効なコマンドなど)status_of_proc -p $PIDFILE "$DAEMON" "$NAME"は、失敗を正しく報告します。
短所:なし。

これが勝者です-うまく機能しているように見える最も簡単で、きちんとしたソリューションです。


7

通常start-stop-daemon、バックグラウンドで実行しているときに標準ファイル記述子を閉じます。のマニュアルページからstart-stop-daemon

-C、--no-close
デーモンをバックグラウンドに強制するときにファイル記述子を閉じません。デバッグの目的で使用され、プロセス出力を確認したり、ファイル記述子をリダイレクトしてプロセス出力をログに記録したりします。--backgroundを使用する場合にのみ関連します。

これは私のために働きました:

    start-stop-daemon -b -C -o -c \ 
         $DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1

4

古いメーリングリストを引用:

https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html

簡単です-そしておそらくあなたがstart-stop-daemonを唯一使用したいのなら-それを回避するには、以下を含む小さなスクリプトを作成します:

#!/bin/sh
exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log

次に、そのスクリプトをstart-stop-daemonの引数として使用します。

しかし、おそらく本当の問題は、そもそもstart-stop-daemonを使用する必要があるかどうかでしょうか。


3

"$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2>&1"がログファイルのファイル記述子を閉じるかどうかはわかりません...つまり、デーモンが永久に実行されるかどうかはわかりませんそのlogrotateまたはディスク領域をクリーンアップするための他のメカニズムが機能します。>>ではなく>であるため、推奨されるコマンドは、再起動時に既存のログも切り捨てます。デーモンがクラッシュした理由を確認し、デーモンが自動的に再起動する場合は、あまり役に立ちません。

別のオプションは、「$ DAEMON | logger」かもしれません。ロガーは、syslog(/ var / log / messages)にログを記録するコマンドです。stderrも必要な場合は、「$ DAEMON 1>&2 | logger」を使用できると思います


あなたは正しいです、>>それはあなたが今logrotateルールを作成するべきであることを意味しますが、デーモンには一般的により適切です!
joeytwiddle 2013年

ディスクスペースに関しては、ファイルを切り捨てるメソッドはスペースをすぐに戻します(少なくともextファイルシステムの下で)。ただし、まだ書き込まれているファイルを単に削除するメソッドには注意してください。ハンドルが解放されるまでスペースは再利用されず、手動で切り捨てるファイルノードを見つけることができなくなります。
joeytwiddle 2013年

ここで私のポイントの@joeytwiddleの部分は、ファイルハンドルが閉じられない場合、logrotateがログのローテーションに失敗する状況があることです。
nairbv 2013年

--no-close ... | logger私には機能しません(Debian 7.3、start-stop-daemon 1.16.12)。/ var / log / messagesに値が入力されていますが、start-stop-daemonスクリプトは戻りません:-)。あり、なしで試してみました1>&2
hgoebl 2014年

hgoebl "cmd | logger"式を引用符で囲む必要があるため、インタープリターは、開始-停止-デーモン式ではなく、ロガーにパイプしている "cmd"であることを認識します。
Wexxor 2015

2

それがbashであると仮定すると(他のシェルでもこれを許可している場合があります)、次の行:

exec >>/tmp/myDaemon.log

今後のすべての標準出力をそのファイルに送信します。これはexec、プログラム名がなければ、リダイレクトの魔法をかけるだけだからです。bashmanページから:

コマンドが指定されていない場合、リダイレクトは現在のシェルで有効になります。

もちろん、このファイルの管理は別の問題です。


この行が配置されるはずの場所を明確にできますか?start-stop-daemon最初の質問が述べた行の直後?
Abdull 2016

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.