コンテクスト:
EXIT疑似信号のサブシェルとトラップを含むbashスクリプトがありますが、。の間に割り込みを適切にトラップしていませんrsync
。次に例を示します。
#!/bin/bash
logfile=/path/to/file;
directory1=/path/to/dir
directory2=/path/to/dir
cleanup () {
echo "Cleaning up!"
#do stuff
trap - EXIT
}
trap '{
(cleanup;) | 2>&1 tee -a $logfile
}' EXIT
(
#main script logic, including the following lines:
(exec sleep 10;);
(exec rsync --progress -av --delete $directory1 /var/tmp/$directory2;);
) | 2>&1 tee -a $logfile
trap - EXIT #just in case cleanup isn't called for some reason
スクリプトの考え方は次のとおりです。重要なロジックのほとんどは、ログファイルを介してログファイルにパイプされるサブシェルで実行されるため、すべてをログに記録するためにメインロジックのすべての行tee
を実行する必要はありません。tee
サブシェルが終了するか、何らかの理由でスクリプトが停止すると(EXIT疑似信号はこれらすべてのケースをキャプチャする必要があります)、トラップはそれをインターセプトしてcleanup()
関数を実行し、トラップを削除します。rsync
andsleep
コマンド(スリープは単なる例です)は、実行中に親スクリプトを強制終了した場合にゾンビプロセスが作成されないようにするために実行されます。またexec
、実行時間が長くなる可能性のある各コマンドは、独自のサブシェルにラップされます。exec
終了すると、スクリプト全体が終了することはありません。
問題:
kill
exec / subshellwrappedコマンドの実行中に(またはCTRL + Cを介して)スクリプトを中断するsleep
と、トラップが正しく機能し、「クリーンアップ!」と表示されます。エコーしてログに記録しました。rsync
コマンド中にスクリプトを中断するrsync
と、endが表示され、画面に書き込みrsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [sender=3.0.6]
ます。その後、スクリプトは終了します。クリーンアップもトラッピングもありません。なぜ中断/殺害はrsync
トラップをトリガーしないのですか?
rsyncでスイッチを使用してみました--no-detach
が、何も変わりませんでした。私はbash4.1.2、rsync 3.0.6、centOS6.2を持っています。