在这些情况下,Bash 不会在通配符中执行分词:
- 赋值的 LHS 或 RHS,索引数组除外
var=$value # simple variable declare -A hash key="key with a space" hash[$key]=$value # index of an associative array arr=$(echo "1 2 3") # word splitting does happen here
- 里面
[[ ]]
var="one two" if [[ $var = *" "* ]]; then ... # check if var has a space in it if [[ $(echo "one two") = $var ]]; then # use the output of command substitution to compare with var
- 里面
(( ))
((sum = $(echo "99 + 1"))) # assigns 100 to sum
- 在这里字符串
cat <<< * # gives '*' as the output
是否有明确的 Bash 执行或不执行分词和通配的情况列表?
这通常是它不能或没有意义的情况,因此非列表上下文。但是,它在非列表上下文中执行此操作,但是当它导致多个项目或将这些项目与空格连接时会抱怨。
此外,重要的是要区分通配符模式匹配和文件名生成或通配,即生成与模式匹配的文件名列表。
例如 in
[[ foo = * ]]
,没有 globbing,因为它*
没有扩展到当前目录中的非隐藏文件列表,但*
仍被解释为模式(这里它返回 true与模式foo
匹配*
)。通过这里的拆分,我们指的是在不带引号的参数扩展 (
$param
)、命令替换 ($(...)
and`...`
) 和算术扩展 ($((...))
and$[...]
) 上使用列表上下文中$IFS
的特殊参数进行的隐式拆分。我们将在
*
下面举个例子。作为一种模式,它匹配任何字符序列。作为一个 glob,它扩展到当前目录中的所有非隐藏文件(服从dotglob
,GLOBIGNORE
...)。以下适用于
bash
,其他外壳有变化。不会发生拆分和通配的情况:
引用时(带
'*'
,"*"
,\*
,$'*'
,$"*"
)。在此处的文档中(无论是否引用分隔符):
内部算术表达式:
echo $((2 * 2))
(*
不是 globbed 而是$((...))
经历 split+glob,尝试之后IFS=4
)array[2 * 2]=4
// .${array[2 * 2]}
_exec {array[2*2]}>&1
请注意,您需要unset -v 'a[1]'
([1]
是通配符) 中的引号。((2 * 2))
echo $[2 * 2]
标量变量赋值:
var=*
array[x]=*
hash[key]=*
array=([1]=*)
(例如,旧版本的旧版本bash
曾经在那里进行 globbing,并且1=foo
在当前目录中调用了一个文件时会做一些不同的事情)。var+=*
在关联数组键中:
typeset -A hash; hash[**]=value; v=${hash[**]}
. 虽然很特别*
。@
在赋值后
export
//local
///仅在某些情况下typeset
:赋值关键字和变量名,declare
即使是部分也不能被引用,也不能是任何扩展的结果。分配和重定向可能发生在之前,但不能使用。:readonly
=
command
export a=*
x=1 < /dev/null export foo a=*
""export a=*
(POSIX 模式除外)command export a=*
export "a"=*
export a\=*
"$(echo export)" a=*
更多关于局部变量赋值需要引号吗?
case * in (...); esac
case x in (*); esac
(没有 split+glob,但这*
被视为一种模式,它也适用于在未引用的扩展中找到的通配符,如var=*; case x in ($var)
)。里面
[[...]]
。=
但请注意,如果,==
,运算符右侧存在未加引号的通配符,则会完成模式匹配!=
。从 4.4 版开始在这里的字符串。在早期版本中,拆分(虽然不是通配符)已经完成,结果单词用空格连接。
在 shell 处于 POSIX 模式且非交互式时的重定向目标中:
bash -o posix -c 'echo test > *
. 否则,split+glob 将被执行,bash
如果扩展为具有少于或多于 1 个元素的列表,则会报告错误。