Bash中的单引号和双引号混淆

时间:2017-03-25 17:12:42

标签: bash quoting

在bash中,我知道单引号和双引号的general rules,但是当事情嵌套得更深时,我会迷失方向。

例如,

之间的区别是什么
export VAR=$(echo "${VAL}-venv" | awk '{print tolower($0)}')

export VAR=$(echo "${VAL}-venv" | awk "{print tolower($0)}")

之间的关系
$(somecmd "${ROLE_NAME}" | someothercmd)

"$(somecmd "${ROLE_NAME}" | someothercmd)"

1 个答案:

答案 0 :(得分:2)

awk '{print tolower($0)}'

阻止shell展开$0。 Awk可以看到$0

awk "{print tolower($0)}"

使shell将$0扩展为当前脚本或shell的名称,类似于交互式会话中的-bash。 Awk可以看到

print tolower(-bash)

因为它不知道任何名为bash的变量,所以它将其初始化为0.

$(somecmd "${ROLE_NAME}" | someothercmd)

返回

的输出
somecmd "${ROLE_NAME}" | someothercmd

并且输出经历了单词拆分和全局扩展;

"$(somecmd "${ROLE_NAME}" | someothercmd)"

做同样的事情,但不会发生分词和全球扩张。

但是,如果命令替换位于赋值的右侧,则默认情况下会禁止通配和分词:

var=$(somecmd "${ROLE_NAME}" | someothercmd)

相当于

var="$(somecmd "${ROLE_NAME}" | someothercmd)"

但引用它并没有什么坏处。

请注意"默认情况下被禁止"声明仅适用于整个右侧; 中,你仍然需要引用。处理数组时这很重要:观察

$ myfunc () { echo 1 2 3; }                  # Generates three words
$ arr=($(myfunc))                            # Unquoted within ()
$ declare -p arr
declare -a arr='([0]="1" [1]="2" [2]="3")'   # Three array elements
$ arr=("$(myfunc)")                          # Quoted within ()
$ declare -p arr
declare -a arr='([0]="1 2 3")'               # One array element

最后,"在右侧自动引用仅适用于扩展,即var=$1(不需要引号)或var=$(command)$()周围不需要引号在command本身内可能需要。当右侧包含空格时,适用:var=a b c 分配{{1} } to var。它尝试将环境变量a b c设置为值var,然后使用参数a运行命令b