tarはアーカイブ作成が最後まで完了しても終了ステータスが 0 以外になることがある!
tar コマンドはアーカイブ作成時にワーニングが発生することがあり、ワーニングが起きてもアーカイブ作成自体は最後まで完了してくれるので、簡易なバックアップ用途であれば大抵無視してよいのだが終了ステータスが 1
になってしまうので、終了しないようにしましょう。(ちゃんと考えるならファイルシステムやブロックデバイスレベルでスナップショットを取るところ)
なお致命的エラーの場合は 2
とかで終了するのでこれは止まって良いです。
駄目な例
# !/bin/bash
set -e
tar cfz tmp.tar.gz target/
mv tmp.tar.gz target.tar.gz
↑これだとファイルのアーカイブ中に以下のような状況が起きた際などに最後までアーカイブ作成は完了するが、終了ステータスが 1
になってしまい。そこでスクリプトが終了してしまう。
- アーカイブ開始した時より後にファイルの更新があった時
tar: target/file: file changed as we read it
tar: target/file: 読み込んだファイルが変更されています
- アーカイブ開始した時に存在したファイルが消えたとき
tar: File removed before we read it
tar: 読み込み以前に削除されました
- アーカイブ開始した時よりファイルサイズが小さくなった時
tar: target/file: File shrank by 12345678 bytes; padding with zeros
tar: target/file: 12345678 バイト小さくなったので、ゼロで埋めます
改善例
# !/bin/bash
set -e
tar cfz tmp.tar.gz target/ || [[ $? == 1 ]]
mv tmp.tar.gz target.tar.gz
終了ステータスが 0 または 1 でも終了しないようにしたので、tarでワーニングが起きても最後の mv まで実行されるようになった。
なおワーニング表示自体出てほしくない場合は --warning=no-file-changed
--warning=no-file-removed
--warning=no-file-shrank
などのオプションを tar につけてやれば良い。ただしこれはワーニングメッセージを抑止するだけで、終了ステータスはやはり 1
になってしまうので上記対応は必要。