Mysql

如何將包含雙引號的參數傳遞給 shell 腳本函式?

  • December 11, 2017

我在 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

如果我刪除 where 子句,問題就消失了,所以在我看來,由於某種未知的原因,shell 只使用了 where 子句的第一個單詞,並將第二個單詞(the IN)解析為數據庫名稱。

然後我把它換成了

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

但它沒有用。我現在不知道該怎麼辦,感謝任何幫助……

未引用$@的是問題。它擴展到函式的所有參數,然後,使它們受到分(和萬用字元)的影響。把它放在引號中:

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

原則上,其他變數也應該被引用 ( "${REMOTE_USERNAME}"),儘管使用者名和數據庫名稱不太可能包含空格(或 glob 字元)

您實際作為參數傳遞的字元串不包含任何雙引號。在 shell 處理(刪除)引號之後,它只是字元串,如果您直接啟動它而不是通過其他函式啟動它,這就是它--where=INFOCODE IN (SELECT ... = '.OC')的方式。mysqldump加上引號"$@"可以保持這種狀態。

當然,對於標題中問題的答案,您可以通過反斜杠轉義它們或將它們放在單引號中來傳遞文字雙引號,就像任何其他命令一樣:

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

引用自:https://unix.stackexchange.com/questions/410179