[解決済み] unixで任意のスクリプトをデーモン化するには?
質問
私は、任意の一般的なスクリプトやコマンドを デーモン .
よくあるケースが2つあるので、対処していきたいと思います。
-
永遠に実行されるはずのスクリプトがあります。 もし死ぬことがあったら (または再起動したら)、再起動します。 同時に 2 つのコピーを実行させないようにします (コピーがすでに実行されている場合は検出し、その場合は起動しないようにします)。
-
永遠に繰り返し実行し続けたい簡単なスクリプトまたはコマンド ライン コマンドがあります (実行の間に短い休止時間があります)。 繰り返しますが、スクリプトの 2 つのコピーを同時に実行することを許可してはいけません。
もちろん、ケース 2 のスクリプトの周りに "while(true)" ループを書き、ケース 1 の解決策を適用することは簡単ですが、より一般的な解決策は、ケース 1 のスクリプトにも適用されるため、直接ケース 2 を解決するだけです (スクリプトが決して死ぬことを意図していない場合は、単に短いか休止しないようにしたい場合があります (もちろん、スクリプトが本当に が は決して死なないのであれば、一時停止は実際には重要ではありません)。
解決策は、たとえば、既存のスクリプトにファイルロックコードや PID 記録を追加するようなものではないことに注意してください。
より具体的には、私は次のように実行できるプログラム "daemonize" が欲しいです。
% daemonize myscript arg1 arg2
とか、例えば
% daemonize 'echo `date` >> /tmp/times.txt'
とすると、times.txt に追加される日付のリストがどんどん増えていきます。(上記のケース1のように、daemonizeへの引数が永遠に実行されるスクリプトである場合、daemonizeはまだ正しいことを行い、必要なときにそれを再起動することに注意してください)。 それから私は、上記のようなコマンドを .login に置き、毎時または毎分 (それが予期せず死ぬことをどの程度心配しているかに依存) にそれをクーロンすることができました。
注意: デーモン化スクリプトは、同じコマンド文字列が再びデーモン化された場合、2番目のコピーを起動しないように、デーモン化しているコマンド文字列を記憶する必要があります。
また、ソリューションは理想的には OS X と Linux の両方で動作する必要がありますが、どちらか一方のためのソリューションも歓迎します。
EDIT: もしあなたがそれを
sudo daemonize myscript myargs
.
(私の考え方が間違っていたり、手っ取り早い部分的な解決策があれば、それもぜひ教えてください)
追記:一応、役に立ちます。 はこちらです。 を参照してください。
そして この の回答には、任意のスクリプトを手早く悪者にするための便利なイディオムがあります。
どのように解決するのですか?
Unixでは、nohupと&演算子を使えば、どんな実行ファイルでもデーモン化することができます。
nohup yourScript.sh script args&
nohupコマンドは、スクリプトを殺すことなくシェルセッションをシャットダウンすることができ、一方&はスクリプトをバックグラウンドに置き、セッションを継続するためのシェルプロンプトを取得します。このコマンドの唯一の小さな問題は、標準出力と標準エラーが両方とも ./nohup.out に送られるため、この方法で複数のスクリプトを起動した場合、それらの出力が絡み合ってしまうことです。より良いコマンドは、次のようになります。
nohup yourScript.sh script args >script.out 2>script.error&
これは、標準出力はあなたが選んだファイルに、標準エラーはあなたが選んだ別のファイルに送ります。もし、標準出力と標準エラーの両方に一つのファイルを使いたい場合は、これを使うことができます。
nohup yourScript.sh script args >script.out 2>&1 &
2>&1 は、標準エラー(ファイル記述子2)を標準出力(ファイル記述子1)と同じファイルにリダイレクトするようにシェルに指示します。
コマンドを一度だけ実行し、終了したら再起動させるには、このスクリプトを使用することができます。
#!/bin/bash
if [[ $# < 1 ]]; then
echo "Name of pid file not given."
exit
fi
# Get the pid file's name.
PIDFILE=$1
shift
if [[ $# < 1 ]]; then
echo "No command given."
exit
fi
echo "Checking pid in file $PIDFILE."
#Check to see if process running.
PID=$(cat $PIDFILE 2>/dev/null)
if [[ $? = 0 ]]; then
ps -p $PID >/dev/null 2>&1
if [[ $? = 0 ]]; then
echo "Command $1 already running."
exit
fi
fi
# Write our pid to file.
echo $$ >$PIDFILE
# Get command.
COMMAND=$1
shift
# Run command until we're killed.
while true; do
$COMMAND "$@"
sleep 10 # if command dies immediately, don't go into un-ctrl-c-able loop
done
第一引数は使用するpidファイル名です。第2引数はコマンドです。そして、それ以外の引数はコマンドの引数です。
このスクリプトに restart.sh という名前を付けると、このように呼び出されます。
nohup restart.sh pidFileName yourScript.sh script args >script.out 2>&1 &
関連
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] ディレクトリが存在しない場合のみmkdirする方法は?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] すべてのディレクトリとサブディレクトリを再帰的にgrepするにはどうしたらいいですか?
-
[解決済み] LinuxのシェルスクリプトでYes/No/Cancelの入力を促すにはどうしたらいいですか?
-
[解決済み] なぜPerl 5の関数プロトタイプはダメなのか?
-
[解決済み] Perlのハッシュのキーを反復処理する最も安全な方法は何ですか?
-
[解決済み] Perlで "my "キーワードはどのように使うべきですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Pythonでデーモンを作成する方法は?
-
[解決済み] PerlからUTF-8を出力するにはどうしたらいいですか?
-
[解決済み] Perlでファイルが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] なぜPerl 5の関数プロトタイプはダメなのか?
-
[解決済み] Perl のフラグ -pe, -pi, -p, -w, -d, -i, -t?
-
[解決済み] なぜstrictとwarningを使うのか?
-
[解決済み] Perlで文字列が空かどうかをチェックする適切な方法は何ですか?
-
[解決済み] Perlでハッシュを結合するには?
-
[解決済み] Perlで "my "キーワードはどのように使うべきですか?
-
[解決済み] インストールされているCPANモジュールの一覧を取得するにはどうすればよいですか?