2つのシェルスクリプトがあります。 1 つはサーバー上で実行され、いくつかのファイルを一時ディレクトリに書き込みます。その後、ディレクトリはtarアーカイブとしてstdoutに転送されます。最後に(または中断された場合)、一時ディレクトリを削除する必要があります。サーバースクリプト(たとえば、「~/get_dumps.sh」に保存されています)は次のとおりです。
#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
for db in db1 db2 db3
do
pg_dump $db postgres > $db.sql
done
tar cJf - .
rm -r $temp_dir
次のスクリプトを使用して、クライアントからサーバースクリプトを呼び出します。
#!/bin/sh
set -e
temp_dir=`mktemp -d`
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
mkdir /tmp/dumps
ssh server '~/get_dumps.sh' | tar xJf - -C $temp_dir
ls $temp_dir
rm -r $temp_dir
クライアントスクリプトを実行してCtrl-Cを押すと、クライアントまたはサーバーの両方から一時ディレクトリは削除されません。ここではなぜtrap
動作しませんか?
編集:まずset -e
。
答え1
問題はですset -e
。複数のコマンドが一緒にパイプされている間にCtrl-cを押すと、SIGINTはスクリプトに送信されず、他の場所に送信されます。これによりエラーが発生し、set -e
スクリプトが直接終了するように処理されます。パイプ付きスクリプトで確実に使用するには、次のものもキャプチャする必要がset -e
ありますEXIT
。
#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE EXIT
for db in db1 db2 db3
do
pg_dump $db postgres > $db.sql
done
tar cJf - .
この場合、法線はexit
トラップによって処理されるため、とにかく多くの状況で役立ちます。