![如何将包含双引号的参数传递给 shell 脚本函数?](https://linux22.com/image/123428/%E5%A6%82%E4%BD%95%E5%B0%86%E5%8C%85%E5%90%AB%E5%8F%8C%E5%BC%95%E5%8F%B7%E7%9A%84%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92%E7%BB%99%20shell%20%E8%84%9A%E6%9C%AC%E5%87%BD%E6%95%B0%EF%BC%9F.png)
我在 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')\""
但没有成功。我现在不知道该怎么办,非常感谢任何帮助......
答案1
未引用的$@
是问题。它扩展到函数的所有参数,然后使它们服从分词(和通配符)。将其放在引号中:
dump_table () {
mysqldump --user=... --lock-tables=false "$@"
}
"${REMOTE_USERNAME}"
原则上,其他变量也应该被引用 ( ),尽管用户名和数据库名称不太可能包含空格(或通配符)
您实际作为参数传递的字符串不包含任何双引号。在 shell 进行引号处理(删除)之后,它只是字符串,如果您直接启动它而不是通过其他函数启动它,--where=INFOCODE IN (SELECT ... = '.OC')
这就是看到它的方式。mysqldump
加上引号就"$@"
可以保持这种状态。
当然,对于标题中问题的答案,您可以通过反斜杠转义它们或将它们放在单引号中来传递文字双引号,就像任何其他命令一样:
somefunc "their name was \"$name\""
somefunc 'their name was "John"'