使用括号扩展范围中的变量馈送到for循环

时间:2012-03-28 15:41:59

标签: bash for-loop brace-expansion

这是myscript.sh

#!/bin/bash
for i in {1..$1};
do
    echo $1 $i;
done

如果我运行myscript.sh 3,则输出为

3 {1..3}

而不是

3 1
3 2
3 3

显然$3包含正确的值,那么为什么for i in {1..$1}的行为与我直接编写for i in {1..3}的行为相同?

5 个答案:

答案 0 :(得分:67)

你应该使用C风格的循环来完成这个:

for ((i=1; i<=$1; i++)); do
   echo $i
done

这可以避免外部命令和讨厌的评估语句。

答案 1 :(得分:27)

因为大括号扩展在变量扩展之前发生。 http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion

如果你想使用大括号,你可能会有这样严峻的事情:

for i in `eval echo {1..$1}`;
do
    echo $1 $i;
done

总结:Bash很卑鄙。

答案 2 :(得分:15)

您可以使用seq命令:

for i in `seq 1 $1`

或者您可以使用C风格的for...loop

for((i=1;i<=$1;i++))

答案 3 :(得分:2)

这是一种在大括号中展开变量而不使用eval 的方法:

end=3
declare -a 'range=({'"1..$end"'})'

我们现在有一系列很好的数字:

for i in ${range[@]};do echo $i;done
1
2
3

答案 4 :(得分:1)

我知道你在标题中提到了bash,但我想补充一点,'for in {$ 1 .. $ 2}'在zsh中按预期工作。如果您的系统安装了zsh,您只需将shebang更改为zsh。

在{$ 1 .. $ 2}中使用带有'for i'的示例还有一个额外的好处,即1美元可以低于2美元并且它仍然有效,如果你想要的话,这需要相当多的麻烦具有C风格的循环的灵活性。