Bash 如何解析包含变量的命令中的引号

Bash 如何解析包含变量的命令中的引号,bash,Bash,在用于转储mysql数据库表的简单shell脚本中考虑以下内容: if [ $account -eq 1 ]; then echo "Dumping user table ... " mysqldump --host='dbhost.com' --user=someUser -p'somePW' dbName --no-create-info --single-transaction --tables user --where="id=${USER_ID}" > account

在用于转储mysql数据库表的简单shell脚本中考虑以下内容:

if [ $account -eq 1 ]; then
  echo "Dumping user table ... " 
  mysqldump --host='dbhost.com' --user=someUser -p'somePW' dbName  --no-create-info --single-transaction --tables user --where="id=${USER_ID}" > account_data/user.sql
fi
如何正确解析/引用上述命令

在-x模式下运行显示以下内容:

mysqldump --host=dbhost.com --user=someUser '-psomePW' dbname --no-create-info --single-transaction --tables user --where=id=283
它仍然有效,但看起来不应该让参数不带引号,密码参数上的单引号包含了整个参数


为什么,巴什,为什么

双引号和单引号并不神奇。它们只是保护shell不以其他方式解释内容

单引号防止shell解释其中的任何内容。在单引号字符串中唯一特殊的是单引号,它结束字符串

双引号可以防止文件名全局切换等,但允许变量扩展等

这两个引号都可以防止shell分词(将输入拆分为空格中的单词)

这条线

echo foo bar baz
是四个字的壳

这两个

echo "foo bar baz"
echo 'foo bar baz'
有两个“词”

删除引号后,任何与之接触的单词都由shell组合,因此这也是两个“单词”

现在让我们看看你们的例子

mysqldump --host='dbhost.com' --user=someUser -p'somePW' dbName  --no-create-info --single-transaction --tables user --where="id=${USER_ID}" > account_data/user.sql
mysqldump --host=dbhost.com --user=someUser '-psomePW' dbname --no-create-info --single-transaction --tables user --where=id=283
假设
USER\u ID
的值为
283

展开变量并从两者中删除引号,我们得到

mysqldump --host=dbhost.com --user=someUser -psomePW dbName  --no-create-info --single-transaction --tables user --where=id=${USER_ID} > account_data/user.sql
mysqldump --host=dbhost.com --user=someUser -psomePW dbname --no-create-info --single-transaction --tables user --where=id=283
你知道为什么这两种引用方式都是一样的。结果是一样的

引用在命令执行之前完成。命令看不到引号,就像它看不到变量本身一样

如果在shell中运行
set-x
,shell将在运行命令时向您显示将要运行的命令(以显示它看到的“单词”的格式)

如何选择引用参数,如
--host='dbhost.com'
,取决于个人风格和值。这些引语是没有必要的。它们可以有效地绕过整个字符串(
'--host=dbhost.com'
),也可以任意绕过参数的任何部分(
--hos't='dbhost.com

如果您想详细了解所有这些是如何工作的,您可以阅读POSIX规范的一节

mysqldump --host=dbhost.com --user=someUser -psomePW dbName  --no-create-info --single-transaction --tables user --where=id=${USER_ID} > account_data/user.sql
mysqldump --host=dbhost.com --user=someUser -psomePW dbname --no-create-info --single-transaction --tables user --where=id=283