本格的なinit.dスクリプト(SysVスタイル)またはrc.localファイルからの単純な1行の呼び出しから、進行中の(サービスのような)プロセスを開始すると、次のような特有の問題が発生します。
su someuser -c "/home/someuser/watchdog.sh &"
Watchdog.shに以下が含まれている場合:
#!/bin/bash
cd /home/someuser
until ./eventMonitoring.py
do
echo "Program crashed with exit code $?. Starting again..." >&2
sleep 1
done
プロセスリストには、常に1つの追加プロセスが残っています。
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
Init.dスクリプトから起動した場合(ソース: https://github.com/ivankovacevic/userspaceServices )
私は同じプロセスを取得しますが、それはstartpar -f-userspaceServicesです
そのプロセスは一体何ですか? startparのmanページを見るとき、なぜ-f引数の言及がないのですか?別のユーザーとして起動時にプロセスを開始するという点で私は何を間違っていますか?他のinit.dスクリプトにそのプロセスが存在しないのはなぜですか?
誰かがこの問題についていくつかの光を当てるのを手伝ってくれませんか?
注:私のシステムはDebian Wheezy 7.4.0です
更新!
プログラマーの観点からstartparの動作について説明するために、stackoverflowに関する新しい質問を開きました。
https://stackoverflow.com/questions/22840360/figuring-out-what-startpar-c-sysvinit-is-doing
これをさらに調査した結果、解決策が見つかりました。これで、正しく行う方法はわかりましたが、startparがなぜそのように動作したのかまだわかりません。ですから、誰かが介入してそれを説明することをいとわないのであれば、私はこれよりもその答えを喜んで受け入れます。
基本的に問題は、標準入力、標準出力、および標準エラーをファイルまたは/ dev/nullにリダイレクト(または閉じる)せずに、何らかの理由でstartpar( "複数の実行レベルのスクリプトを並行して実行するために使用")プロセスは、私の理解では、起動中に他のプロセスを起動するプロセスであり、そのため、私のこのスクリプト。スクリプトは起動しましたが、それ自体は実行を終了せず、プロセスリストに次のように表示される段階で残りました。
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
startparのソースコードはここにあります: http://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c ?root = sysvinit&view = markup
私はそれをざっと見て、stackoverflowに投稿した新しい質問で最初の分析を行いました。ここで質問に追加した[〜#〜] update [〜#〜]でリンクを見つけます。
私が使用した最終的な解決策はこれです:
su someuser -c "Nohup some_script.sh >/dev/null 2>&1 &"
su-ユーザーIDをsomeuserに置き換えます
-c-指定されたコマンドを実行するためのsu引数
Nohup-ハングアップの影響を受けないコマンドを実行します。親プロセスが子プロセスを終了するケースを防ぐため。念のためここに追加しました。しかし、私の特定のケースでは実際には効果がありません。必要かどうかは環境によって異なります(checkshopt)
>/dev/null-標準出力を何にもリダイレクトせず、基本的に無効にします。
2>&1-標準エラー(2)出力を標準出力(1)にリダイレクトし、これはnullにリダイレクトされます
&-バックグラウンドにデタッチします。これにより、標準入力も/ dev/nullにリダイレクトされます。
私のシステムで実行されている他の既知のデーモンのファイル記述子を見ると、/ dev/nullへのリダイレクトが一般的であることがわかります。そして、一部のデーモンプロセスだけが、実際にstdin、stdout、stderrを完全に閉じています。これは、たとえばこれによって達成できます。
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
実際には、それはすべて同じであり、プロセスをバックグラウンドデーモンとしてクリーンにデタッチするために必要なもの(どちらのオプションでも)です。