web-dev-qa-db-ja.com

Bashスクリプトとパスワード内の特殊文字のエスケープ

私はすでにここで尋ねられた多くの質問を読んできましたが、どういうわけか私のために何も機能していません。リモートマシン上のデータベースをダンプするパスワードを送信する必要があるbashスクリプトがあるので、

!/bin/sh
/usr/bin/ssh -p 91899 user@remoteHost mysqldump -u db_user -p#8111*@uu( my_database |  gzip -c >  my_database.sql.gz

さて、このパスワードにはあらゆる種類の特殊文字があります:#8111*@uu(

上記のコマンドを単一引用符で囲んでパスワードを使用して直接実行すると、動作します。

/usr/bin/ssh -p 91899 user@remoteHost mysqldump -u db_user -p'#8111*@uu(' my_database |  gzip -c >  my_database.sql.gz

単一引用符がないと、末尾の '('でエラーが発生します。

また、パスワードの文字を次のようにエスケープしようとしました:

!/bin/sh
/usr/bin/ssh -p 91899 user@remoteHost mysqldump -u db_user -p'\#8111\*\@uu(' my_database |  gzip -c >  my_database.sql.gz

次に、アクセス拒否エラーが表示されます。

私も「ソース」を使用しようとしました。別のファイルにパスワードを保存する:

ファイルpass.cre

MYPASSWORD='#8111*@uu('

次に、そのファイルをbashスクリプトに含めます。

!/bin/sh
source pass.cre
/usr/bin/ssh -p 91899 user@remoteHost mysqldump -u db_user -p$MYPASSWORD my_database |  gzip -c >  my_database.sql.gz

ファイルから$ MYPASSWORDを読み取っているように見えますが、無効な文字のエラーが再び発生しています。

私は何が欠けているのですか?

8
Saahib

二重引用符を2回使用し、エスケープし、エスケープしない:-p"\"$MYPASSWORD\""

#!/bin/sh
source pass.cre
/usr/bin/ssh -p 91899 user@remoteHost 'mysqldump -u db_user -p"\"$MYPASSWORD\"" my_database |  gzip -c >  my_database.sql.gz'

または他のバージョン

/usr/bin/ssh -p 91899 user@remoteHost "mysqldump -u db_user -p\"'io#bc@14@9$#jf7AZlk99'\" my_database | gzip -c > my_database.sql.gz"

% source pass.cre
% ssh user@Host mysqldump -u root -p$MYPASSWORD    
user@Host's password: 
zsh:1: bad pattern: -p#8111*@uu(

% source pass.cre
% ssh user@Host mysqldump -u root -p"$MYPASSWORD"   
user@Host's password: 
zsh:1: bad pattern: -p#8111*@uu(

% source pass.cre
% ssh user@Host mysqldump -u root -p"\"$MYPASSWORD\""
user@Host's password: 
Warning: Using a password on the command line interface can be insecure.
7
A.B.

問題は、文字列が2回解釈され、1回はローカルシェルによって、もう1回はsshが実行されているリモートシェルによって解釈されることです。したがって、次のいずれかを使用して2回引用する必要があります。

-p\''#8111*@uu('\'
-p"'#8111*@uu('"

編集:コマンド全体を""二重引用符で囲む場合、$を含むパスワードに問題があります。これを回避するには、コマンドを単一引用符で囲む必要があります。ただし、-p値は2回解釈されるため、単一引用符で囲む必要があります。そのため、単一引用符の中に単一引用符が必要です。

これは、次の例のように単一引用符\')を使用して実行されます。

'I don'\''t like Java'

文字列I don't like Javaを提供します。したがって、二重引用符で囲まれた例は、単一引用符で囲まれたものになります。

/usr/bin/ssh -p 91899 user@remoteHost 'mysqldump -u db_user -p'\''io#bc@14@9$#jf7AZlk99'\''my_database | gzip -c > my_database.sql.gz'

あなたはただそれを愛していませんか?

2
meuh