Lou*_*Lou 1 bash array autocomplete shell-script null
我最近发现不能将空字符串传递给 Bash 数组。这很棘手,因为我试图将空字符串值插入到数组中。
然而,我注意到 Bash 完成变量 COMP_WORDS 可以包含空值。
我编写了一个虚拟完成脚本来说明这一点,并启用了调试选项:
1 #!/bin/bash
2 _comp() {
3 set -xv
4 for i in ${!COMP_WORDS[@]}; do
5 echo "<${COMP_WORDS[$i]}>"
6 done
7 set +xv
8 local cur=${COMP_WORDS[$COMP_CWORD]}
9
10 local arr=(apple banana mango pineapple)
11 COMPREPLY=()
12 COMPREPLY=($(compgen -W "${arr[*]}" -- $cur))
13
14 }
15
16 complete -F _comp dummy
Run Code Online (Sandbox Code Playgroud)
如果我获取该文件,然后输入以下内容:
dummy apple banana
Run Code Online (Sandbox Code Playgroud)
然后,如果我将光标移回苹果和香蕉之间的中间空间(下面用下划线表示)...
dummy apple _ banana
Run Code Online (Sandbox Code Playgroud)
然后,如果我点击选项卡,我会从生成的调试中得到以下输出,显示四个数组元素,“虚拟”“苹果”“香蕉”
for i in '${!COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<>'
<>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
Run Code Online (Sandbox Code Playgroud)
因此 COMP_WORDS 数组显然能够存储某种空字符串。尽管有趣的是,如果我使用常规 for 循环访问数组元素而不是索引,则不会发生这种情况。即,如果我将调试部分中的 for 循环更改为此...
for i in ${COMP_WORDS[@]}; do
echo "<$i>"
done
Run Code Online (Sandbox Code Playgroud)
然后我得到以下调试输出,仅显示三个数组元素: 'dummy' 'apple' 'banana'
for i in '${COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
Run Code Online (Sandbox Code Playgroud)
我尝试用 - 来回显数组的长度${#COMP_WORDS[@]}- 对于此输入,它显示的长度为四。所以它显然包含四个元素,其中一个是空字符串。
对我来说,这似乎是非常奇怪的行为。我的问题有两个:
当普通数组显然不能存储空字符串时,COMP_WORDS 数组能够存储空字符串的解释是什么?
为什么当我使用常规 for 循环时看不到空字符串,但当我通过索引访问数组元素时却可以看到它?
您似乎将空字符串""与 NULL 字符混淆了\0。他们不一样。您可以在数组和变量中使用空字符串:
$ a=(aa "" "b")
$ echo "${#a[@]}"
3
$ printf -- '- %s\n' "${a[@]}"
- aa
-
- b
$ for i in "${a[@]}"; do
> printf '%s\n' "$i"
> done
aa
b
Run Code Online (Sandbox Code Playgroud)
Bash 中的一些条件表达式甚至允许测试字符串是否为空:
-z 字符串
Run Code Online (Sandbox Code Playgroud)True if the length of string is zero.-n 字符串 字符串
Run Code Online (Sandbox Code Playgroud)True if the length of string is non-zero.
另请参见何时需要双引号?