tl;目录
在 bash 中,大括号扩展发生在波浪号扩展之前。但是,波浪号前缀似乎在变量赋值之前扩展,而大括号扩展则没有。为什么?
细节和例子
bash 中的大括号扩展被记录为发生在波浪线扩展之前:
大括号扩展在任何其他扩展之前执行
据我了解,波浪号扩展发生在变量赋值之前,如下例所示:
# UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
tilde=~
echo "$tilde"
# /Users/DeNovo
[[ $tilde == "$HOME" ]] && echo "literal match"
# literal match
# QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
lit_tilde='~'
echo "$lit_tilde"
# ~
# UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
# AS EXPECTED
eval echo "$lit_tilde"
# /Users/DeNovo
[[ $lit_tilde == "~" ]] && echo "literal match"
# literal match
这些例子似乎表明右操作数left=right
在被绑定为左操作数的值之前经历波浪号扩展。
然而,大括号扩展不会发生在变量赋值之前,其行为类似于将文字波浪号绑定到变量(相对于扩展的特殊字符/前缀)
# UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
brace={a..c}
echo "$brace"
# {a..c}
[[ $brace = "a b c" ]] || echo "doesn't match"
# doesn't match
[[ $brace = "{a..c}" ]] && echo "literal match"
# literal match
# SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE
# RESULTS IN BRACE EXPANSION
eval echo "$brace"
# a b c
将这两个扩展合并到一个示例中,您可以看到波浪号扩展发生而大括号扩展没有发生:
combined=~/dir_{a..c}
echo "$combined"
# /Users/DeNovo/dir_{a..c}
大括号防止内部代字号在分配期间扩展
internal_tilde={~,~+}/new_dir
echo "$internal_tilde"
# {~,~+}/new_dir
# vs the same output, not in a variable
echo {~,~+}/new_dir
/Users/DeNovo/new_dir /Your/Working/Directory/new_dir
只是为了澄清,我不是在问如何让变量包含大括号扩展的结果,而是为什么尽管发生在波浪线扩展之前,大括号扩展不会在变量赋值之前发生。有几种方法可以获得所需的行为。这是一个:
# PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
brace_exp="$(echo {a..c})"
echo "$brace_exp"
a b c
[[ $brace_exp = "a b c" ]] && echo "literal match"
# literal match
再说一遍,为什么波浪号扩展发生在变量赋值之前,而大括号扩展(应该发生在波浪号扩展之前)却没有发生在变量赋值之前。大概分配在某种我不知道的方面是特殊的。