非常にうまく機能するシェル MySQL バックアップ スクリプトを作成しました。
次のような特殊文字を含むパスワードでのみ問題が発生します:
xgT{uic[Is?uJ+
。
スクリプトの重要な部分は次のとおりです。
#!/bin/sh
FILE=mysql-$db.$DATE.sql.gz
ssh $SUSER@$SHOST "mysqldump -q -u $MUSER -h $MHOST -p$MPASS $db --no-create-db | gzip -9 > $FILE" 2> $ERROR
次のように変更しました:
ssh $SUSER@$SHOST 'mysqldump -q -u $MUSER -h $MHOST -p'\''$MPASS'\'' $db --no-create-db | gzip -9 > $FILE' 2> $ERROR
ご覧のとおり、私はすでに二重引用符を試しました。しかし、今度はエラーが発生します:
bash: $FILE: ambiguous redirect
パスワードとその他の情報を外部ファイルから取得しています:
DB_HOST=000.000.000.000
DB_DATABASE=dbdame
DB_USER=db user
DB_PASS="xgT{uic[Is?uJ+"
私のスクリプトでは、外部ファイルから情報を取得します。
Source dbserver.conf
MUSER=$DB_USER
MPASS=$DB_PASS
MHOST=$DB_HOST
DBS=$DB_DATABASE
答え1
パスワードでは特殊文字をエスケープする必要があります。したがって、元のパスワードが の場合は、(特殊文字の前にスラッシュ)xgT{uic[Is?uJ+
にする必要があります。xgT\{uic\[Is\?uJ\+
これを行うためにすでに書かれたものを参照することもできます。自動MySQLバックアップただし、毎日、毎週、毎月のバックアップローテーションが必要かどうかはわかりません。ただし、同じルールが適用され、パスワードに特殊文字が含まれている場合は、それらの特殊文字をエスケープする必要があります。
お役に立てれば幸いです!
答え2
はい。特殊文字をエスケープするのに役立ちました:
MPASS=$(printf "%q\n" "$DB_PASS")
しかし、mysqldump にはまだ問題がありました。最終的に、mysqldump にホストを指定しない (-h hostname) 場合、mysqldump は特殊文字を含むパスワードでのみ機能することがわかりました。これはバグのようです。それともそうではないのでしょうか?
残念ながら、mysql サーバーが別のホストであるサイトもあります。したがって、このソリューションは完璧ではありません。
答え3
次のように書きます。
ssh "$SUSER@$SHOST" "mysqldump -q -u \"$MUSER\" -h \"$MHOST\" -p\"$MPASS\" \"$db\" --no-create-db | gzip -9 > \"$FILE\"" 2> "$ERROR"
つまり、コマンドライン引数として使用されるすべての変数は、引用符で囲んで保護する必要があります。変数を二重引用符で囲むことで、式が単一の値として扱われ、シェルがそれを単語に分割しないようにすることができます。"
埋め込まれた は"..."
エスケープする必要があり、 と記述する必要があることに注意してください\"
。より簡単な解決策は、次のように埋め込まれた二重引用符の代わりに一重引用符を使用することです。
ssh "$SUSER@$SHOST" "mysqldump -q -u '$MUSER' -h '$MHOST' -p'$MPASS' '$db' --no-create-db | gzip -9 > '$FILE'" 2> "$ERROR"
最後に、リモート ホストではなく、ローカル ホストに実行するつもりだったのではないかと思います2> "$ERROR"
。実際にはリモート ホストに実行するつもりだったのではないかと思います。これは元のコマンド ラインの別のエラーです。その場合、修正方法は次のとおりです。
ssh "$SUSER@$SHOST" "mysqldump -q -u '$MUSER' -h '$MHOST' -p'$MPASS' '$db' --no-create-db | gzip -9 > '$FILE' 2> '$ERROR'"