私が出くわした全国ネットワークをサーフィンする 興味深い記事 (巧みに説明されているため、ここにテキストで示します)ここで、その作成者は、Bashスクリプトをより堅牢にする方法を示しています。 トラップ.
トラップを使用してbashスクリプトをより堅牢にします
毎日XNUMX時間ごとに実行されるbashスクリプトがあり、ある時点で失敗するか、同じスクリプトが同時にXNUMX回実行されると想像してください。 これらのXNUMXつの状況は、人間の介入を修正する必要があるか、特定の時間に対処できず、システムが一貫性のない状態になるため、非常に不快です。 これに対する解決策は、とりわけ、トラップを使用することです。
トラップは、bashスクリプトの出力を制御するためのシンプルで効果的な方法です。 同じ初期状況に戻りましょう。たとえば、ctrl-cを使用してスクリプトを手動で停止すると、スクリプトが中断され、出力信号が返されます。
INT
そしてそれがで終わる場合
kill
その場合、出力は次のようになります
TERM
.
可能なすべての終了コードは、
kill -l
ただし、最もよく使用されるのは正確に
INT、TERM、EXIT
スクリプトが、たとえば、ファイルと同期することで構成されている場合
rsync
最も賢明なことは、スクリプトを同時に実行できないロックファイルに依存することです。
LOCK = "/ var / run / rsync.lock" if [! -e $ LOCK]; 次に、$ LOCK rsync -avz foo bar rm $ LOCKをタッチします。elseecho "rsyncはすでに実行されています" fi
平易なスペイン語では、上記のスクリプトはロックファイルが存在するかどうかを確認し、存在しない場合は作成してから対応するコマンドを実行し、最後にロックファイルを削除します。 ファイルが存在する場合、スクリプトは、コマンドがすでに実行されていることを示すメッセージをユーザーに送信するだけです。
ただし、問題のある状況が発生すると、ロックファイルが削除されず、不要な効果が損なわれる可能性があります。 解決策は非常に簡単です。
LOCK = "/ var / run / rsync.lock" if [! -e $ LOCK]; 次に、トラップ "rm -f $ LOCK; exit" INT TERM EXIT touch $ LOCK rsync -avz foo bar rm $ LOCK trap --INT TERM EXIT else echo "rsyncはすでに実行中です" fi
このソリューションの特徴は、コマンドがトラップに囲まれているため、信号を受信したときに
INT、TERM、EXIT
スクリプトは停止し、ロックファイルをクリアします。
上記のスクリプトでは、ロックファイルが検証されてから作成されるまでの間に競合状況が発生する可能性があることは言うまでもありません。 考えられる解決策のXNUMXつは、既存のファイルにリダイレクトしないリダイレクトおよびbashのnoclobberモードを使用することです。
LOCK = "/ var / run / rsync.lock" if(set -o noclobber; echo $$> "$ LOCK")2> / dev / null; 次に、トラップ 'rm -f "$ LOCK"; $を終了しますか? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap-INT TERM EXIT else echo "rsyncはすでに実行されています:$(cat $ LCK)" fi
後者の特徴は、すでに述べたように、noclobberモードで使用され、ロックファイルには実行中のプロセスのPIDが含まれていることです。
次のような他の解決策があることにも言及する価値があります
flock
o
solo
ただし、この投稿では、ソリューションをbash自身のリソースと共有したいと思いました。 これでトラップについてもう少し学ぶことができます 優れたガイド.
鮮やかさ! 共有していただきありがとうございます。
いい記事です。'echo "rsyncはすでに実行されています:$(cat $ LCK)" 'を' echo "rsyncはすでに実行されています:$(cat $ LOCK)" 'に変更してください。
よろしく
非常に興味深い記事です、そうです! これは私が保管します。
覚えておくと非常に便利なコマンドです。 投稿で公開したスクリプトで使用して、スクリプトが停止したときに作成したファイルをいくつか削除しました。
非常に興味深いです、はい。