3

我正在编写一个脚本,该脚本在一系列目录中查找文件是否存在,并在找到时通过pushd. 该dirs命令非常令人讨厌,我偶然发现了它的内容的 bash 变量形式,$DIRSTACK

$DIRSTACK是堆栈中的目录数组。始终保证有 1 个条目,即当前工作目录,然后是推送的目录。

我正在尝试遍历目录列表,但似乎无法让 for 循环接受我尝试自动生成的序列长度:

for i in {1..${#DIRSTACK[*]}}; do
  echo ${DIRSTACK[$i]}
done

执行时,bash 失败并出现以下错误:

line 72: {1..2}: syntax error: operand expected (error token is "{1..2}")

老实说,我很难过,因为我已经for i in {1..5}多次手动编写脚本没有问题,并且给出错误消息,看起来数组项扩展的数量完全按照我的意愿工作。

为什么会出现这个错误?

4

2 回答 2

5

如果您在其中有参数,大括号扩展将无法正常工作。这是因为在这种情况下,参数 ,直到大括号展开DIRSTACK才会展开。

从 bash 手册页:

大括号扩展在任何其他扩展之前执行,并且任何其他扩展的特殊字符都保留在结果中。它是严格的文本。Bash 不对扩展的上下文或大括号之间的文本应用任何句法解释。

如果您只是想遍历数组,为什么不使用以下内容?

for i in "${DIRSTACK[@]}"
do
    echo $i
done

或者,如果您想显式使用数组的长度:

for (( i = 0 ; i < ${#DIRSTACK[@]} ; i++ ))
do
    echo ${DIRSTACK[$i]}
done
于 2012-06-20T07:51:51.473 回答
2

与序列表达式类似的构造是使用seq(1)命令。

对于您的具体情况,您可以使用:

for i in $(seq ${#DIRSTACK[*]}); do
  echo ${DIRSTACK[$i]}
done

但是,鉴于您对@dogbane 的回答的评论,这仍然不会做您想要的,因为您仍在迭代数组中的元素数量,但索引超过末尾。

通过使用 bash 的substring expansion可以轻松实现您想要的,它也适用于数组。

for dir in "${DIRSTACK[@]:1}" ; do
  echo $dir
done
于 2012-06-20T09:09:16.243 回答