Mysqldumpでエラーが発生しない場合にのみ、SQLダンプを圧縮したいと思います。間違ったパスワードを入力しようとしましたが、それでもgzipを実行します。
mysqldump -u username -ppassword dbname |& if [ $? == 0 ]; then gzip > test.gz; else echo "error"; fi
私のコマンドの何が問題になっていますか、それとももっと良い解決策はありますか?
|&
を削除できると思います(コマンドセパレータとして「;」を使用できる場合は、stdoutまたはstderrを次の条件にパイプする必要がないためです)。このようなものはおそらく機能するはずです:
#!/bin/bash
mysqldump -u myuser -p mypasswd > mydb.dump
if [[ $? -eq 0 ]]; then
gzip mydb.dump
else
echo >&2 "DB backup failed"
exit 1
fi
編集:gzipの成功を確認するには、次のようにします。
mysqldump -u myuser -p mypasswd | gzip > mydb.dump.gz && echo "success" || echo "failure"
ただし、これはmysqldump
が失敗した場合、つまりgzipがディスクをいっぱいにする以外のほとんどの理由でバックアップが失敗した場合でも成功を報告します。
あなたもすることができます
mysqldump -someparams dump.sql && gzip dump.sql || echo "Backup failed"
または
mysqldump -someparams dump.sql
[[ $? == 0 ]] && gzip dump.sql || echo "Backup failed "
パイプは2つの側面を並列に実行します。これを実行しようとしている方法は概念的に不可能です。mysqldump
の実行と並行してこのテストを実行すると、終了するまでmysqldump
コマンドのステータスをテストできません。 mysqldump
を実行し、終了するのを待ってから、次にgzip
を実行するかどうかを決定する必要があります。
mysqldump
は実行を終了する必要があるため、その出力はどこかに移動する必要があります。おそらく、圧縮しているので、出力が大きくなると予想します。したがって、賢明なオプションはそれを圧縮することです。したがって、出力を無条件に圧縮します。
mysqldump -u username -ppassword dbname | gzip > test.gz
|
ではなく|&
を使用したことに注意してください。ここで|&
を使用しても意味がありません。エラーメッセージがある場合、それらはダンプと混ざり合ってしまい、ダンプを復元することは不可能になります。
まだ解決されていない問題は、mysqldump
が成功したかどうかを検出することです。これがbashまたはkshスクリプト(つまり、#!/bin/bash
ではなく#!/bin/ksh
または#!/bin/sh
などで始まる)であると想定して、 pipefail
オプション。いずれかの部分に障害が発生すると、パイプラインに障害が発生します。 (デフォルトでは、パイプラインのステータスはその右端のコマンドのステータスであり、他のコマンドのステータスは無視されます。)
#!/bin/bash
set -o pipefail -o errexit
tmp="mydump.tmp.$$.gz"
trap 'rm -f "$tmp"' ERR INT TERM HUP
mysqldump … | gzip >"$tmp"
mv "$tmp" mydump.gz
errexit
オプションを設定すると、パイプラインに障害が発生した場合、スクリプトはその時点で終了します(パイプラインと同じエラーステータスで)。したがって、mydump.gz
というファイルは、ダンプが成功した場合にのみ作成されます。 trap
コマンドはトラップを設定し、スクリプトが失敗した場合、またはリストされたシグナルの1つによって強制終了された場合に、一時ファイルが削除されるようにします。
Bash組み込みテーブル$ PIPESTATUS [x]を使用してエラーをトラップすることもできます。
例えば :
$ cmd1 | cmd2 | cmd3 | ..
等々..
次に、どのコマンドが失敗したかを確認します
一時ファイルの使用を避けたい場合、別の解決策は、エラー時に結果のファイルを削除することです。
( mysqldump ... || rm -f test.gz ) | gzip > test.gz
または、明示的なフラグが必要な場合は、次のようにします。
rm -f test.ok
( mysqldump ... && touch test.ok ) | gzip > test.gz
if [[ $? -eq 0 && -r test.ok ]]; then
echo it worked
else
echo something went wrong
fi