web-dev-qa-db-ja.com

mysqldumpがエラーにならない場合にのみgzipする方法は?

Mysqldumpでエラーが発生しない場合にのみ、SQLダンプを圧縮したいと思います。間違ったパスワードを入力しようとしましたが、それでもgzipを実行します。

 mysqldump -u username -ppassword dbname |& if [ $? == 0 ]; then gzip > test.gz; else echo "error"; fi

私のコマンドの何が問題になっていますか、それとももっと良い解決策はありますか?

3
Monkey D Luffy

|&を削除できると思います(コマンドセパレータとして「;」を使用できる場合は、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がディスクをいっぱいにする以外のほとんどの理由でバックアップが失敗した場合でも成功を報告します。

4
Brett Levene

あなたもすることができます

mysqldump -someparams dump.sql && gzip dump.sql || echo "Backup failed"  

または

mysqldump -someparams dump.sql  
[[ $? == 0 ]] && gzip dump.sql || echo "Backup failed "
3
Angel Porlan

パイプは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 | ..
  • cmd1のステータスは変数$ PIPESTATUS [0]になります
  • cmd2のステータスは$ PIPESTATUS [1]になります

等々..

次に、どのコマンドが失敗したかを確認します

2
freeeflyer

一時ファイルの使用を避けたい場合、別の解決策は、エラー時に結果のファイルを削除することです。

( 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
0
roaima