4

我对 bash 脚本很陌生,我显然缺少一些相当基本的理解,因为我无法弄清楚为什么这个脚本没有像我预期的那样运行。我做了一个简单的例子来重现这个问题,它应该制作 3 个文件夹,里面有 3 个文件夹,然后test在每个文件夹中触摸一个文件。

这是脚本:

#!/bin/sh
DIR_LEVEL_1=("1" "2" "3")
for DIR_1 in ${DIR_LEVEL_1[@]}; do
  mkdir $DIR_1
  DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
  echo $DIR_LEVEL_2
  for DIR_2 in ${DIR_LEVEL2[@]}; do
    mkdir $DIR_2
    touch "$DIR_2/test"
  done
done

我遇到的问题是它没有进入第二个 for 循环,我输入了那个 echo,看起来第二个数组没有正确创建,因为脚本的输出是:

1/a
2/a
3/a

这只是数组的第一个元素。

使用-xv标志运行我得到了这个,这表明它没有注意到嵌套的 for 循环(我猜是因为数组没有按照我的意愿创建?)

#!/bin/sh
DIR_LEVEL_1=("1" "2" "3")
+ DIR_LEVEL_1=("1" "2" "3")
for DIR_1 in ${DIR_LEVEL_1[@]}; do
  mkdir $DIR_1
  DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
  echo $DIR_LEVEL_2
  for DIR_2 in ${DIR_LEVEL2[@]}; do
    mkdir $DIR_2
    touch "$DIR_2/test"
  done
done
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 1
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 1/a
1/a
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 2
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 2/a
2/a
+ for DIR_1 in '${DIR_LEVEL_1[@]}'
+ mkdir 3
+ DIR_LEVEL_2=("$DIR_1/a" "$DIR_1/b" "$DIR_1/c")
+ echo 3/a
3/a

所以它只创建第一级文件夹

4

2 回答 2

4

您在这里遇到三个问题:

  1. #!/bin/bash如果你想使用 bash,脚本应该以 bash 开头,而不是#!/bin/sh
  2. echo $ARRAY将只输出数组的第一个元素,而不是整个数组,这就是为什么它看起来只在做第一个元素 - 它不是,但它只是打印第一个元素。用于echo ${ARRAY[@]}输出整个数组。
  3. 当您迭代第二个数组时,您的变量名错误。您的数组是DIR_LEVEL_2,但您正在迭代${DIR_LEVEL2[@]},它是空的(因此没有迭代)。您在2
于 2012-04-17T12:09:54.140 回答
3

好吧,您的脚本的真正问题是您创建DIR_LEVEL_2了 ,但您迭代了DIR_LEVEL2. (注意下划线的区别)。但是,您也忽略了 quote "${array[@]}",这意味着它不会正确拆分单词。除此之外,我是否建议您使用大括号扩展来使整个事情变得更好?

#!/bin/bash

dirs=( {1,2,3}/{a,b,c} )
mkdir -p "${dirs[@]}"
for d in "${dirs[@]}"; do
    touch "$d/test"
done

编辑/后记:我注意到你上面的脚本使用了#!/bin/sh,但你已经标记了这篇文章bash。它们不是同一件事。除非您确定要以 bash 的更大功能集换取 sh 的更大可移植性,否则请使用#!/bin/bash.

于 2012-04-17T12:07:19.263 回答