我在 /tmp 下有两个文件夹。
从终端:
ls -d /tmp/firefox-*
/tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile
或者
compgen -G /tmp/firefox-*
/tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile
我也可以将输出存储在一个数组中:
arr=( $(ls -d /tmp/firefox-*) )
echo $arr
tmp/firefox-sy2vakcj.default-esr-charlie-cache /tmp/firefox-sy2vakcj.default-esr-charlie-profile
echo $arr[1]
tmp/firefox-sy2vakcj.default-esr-charlie-cache
echo $arr[2]
/tmp/firefox-sy2vakcj.default-esr-charlie-profile
到目前为止,一切都很好。
但是如果我从脚本中尝试同样的事情:
...
...
arr=( "$(ls -d /tmp/firefox-*)" ) ||( echo "directory doesn't exist" && exit 1)
#arr=( "$(compgen -G /tmp/firefox-*)" ) ||( echo "directory doesn't exist" && exit 1)
echo "this is a test for arr[1]: $arr[1]"
echo "this is a test for arr[2]: $arr[2]"
...
我得到输出:
从脚本:
这是ls -d
输出:
+ arr=("$(ls -d /tmp/firefox-*)")
++ ls -d '/tmp/firefox-*'
ls: cannot access '/tmp/firefox-*': No such file or directory
+ echo 'directory doesn'\''t exist'
directory doesn't exist
对于compgen -G
,这是输出:
this is a test for arr[1]: /tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile[1]
this is a test for arr[2]: /tmp/firefox-sy2vakcj.default-esr-charlie-cache
/tmp/firefox-sy2vakcj.default-esr-charlie-profile[2]
我的问题:
1.为什么 glob 没有在命令的 subshell 中扩展 ls -d
?
2.使用compgen -G
,数组中的值是如何存储的?输出似乎数组中的每个条目都存储目录条目和第二个具有自己的索引数组的条目?
3.两个命令的终端输出是否与脚本不同,还是我遗漏了什么?
您可能已经使用
set -f
. 展示:当您这样做
arr=( "$(compgen -G /tmp/firefox-*)" )
时,双引号会强制将 compgen 输出存储为数组中的单个元素。在这种情况下,要将输出行读入数组,请mapfile
与进程替换一起使用:看起来您的交互式 shell 是 zsh。除此之外,您缺少需要大括号(3.5.3 Shell Parameter Expansion)的数组元素的参数扩展语法,并且 bash 数组从零开始索引: