二重引用符を含むパラメータをシェルスクリプト関数に渡すには?

二重引用符を含むパラメータをシェルスクリプト関数に渡すには?

私のpull_news.shでは(変数宣言は省略されています):

dump_table () {
   mysqldump --user=${REMOTE_USERNAME} --password=${REMOTE_PASSWORDS} --host=${REMOTE_HOST} --port=${REMOTE_PORT} --single-transaction --lock-tables=false $@
}

pull_news(){
    dump_table --set-gtid-purged=OFF --where="INFOCODE IN (SELECT INFOCODE FROM info_an_newsrelation WHERE MKTPOSTFIX = '.OC')" ${REMOTE_DBNAME} info_an_newscontent > ${DUMPFILE}
}

pull_news

後ろに

$ ./pull_news.sh

私は持っています

mysqldump: Got error: 1044: Access denied for user 'user'@'%' to database 'in' when selecting the database

INwhere句を削除すると問題がなくなるため、不明な理由からシェルはwhere句の最初の単語のみを取り、2番目の単語(the)をNameデータベースに解析するようです。

それから私はそれを置き換えました。

--where="\"INFOCODE IN (SELECT INFOCODE FROM info_an_newsrelation WHERE MKTPOSTFIX = '.OC')\""

しかし、成功しませんでした。今は何をすべきかわかりません。どんな助けでもいただきありがとうございます...

答え1

引用されていないのは$@問題です。関数のすべてのパラメータに拡張され、それを遵守します。噴射(およびワイルドカード)。引用符で囲む:

dump_table () {
   mysqldump --user=... --lock-tables=false "$@"
}

"${REMOTE_USERNAME}"原則として、他の変数も引用符で囲む必要があります()。ユーザー名とデータベース名にスペース(またはワイルドカード)が含まれる可能性はほとんどありません。

実際、パラメータとして渡す文字列には二重引用符は含まれていません。シェルが引用(削除)を行った後はただの文字列だけなので、--where=INFOCODE IN (SELECT ... = '.OC')他の関数を通さずに直接起動すればこれを見ることができます。そのままmysqldumpにするには、引用符を追加してください。"$@"

もちろん、タイトルの質問に対する答えとして、他のコマンドと同様にバックスラッシュでエスケープしたり、一重引用符で囲んだり、リテラル二重引用符を渡したりできます。

somefunc "their name was \"$name\"" 
somefunc 'their name was "John"'

関連情報