在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)"
答案 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
。