47

这是 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}直接写的那样表现呢?

4

5 回答 5

69

您应该使用 C 风格的 for 循环来完成此操作:

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

这避免了外部命令和讨厌的 eval 语句。

于 2012-03-28T21:56:24.800 回答
26

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

如果你想使用大括号,你可以像这样严峻:

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

摘要:Bash 是邪恶的。

于 2012-03-28T15:44:54.383 回答
15

您可以使用seq命令:

for i in `seq 1 $1`

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

for((i=1;i<=$1;i++))
于 2012-03-28T15:45:46.677 回答
2

Here is a way to expand variables inside braces without eval:

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

We now have a nice array of numbers:

for i in ${range[@]};do echo $i;done
1
2
3
于 2015-01-21T12:46:27.110 回答
1

I know you've mentioned bash in the heading, but I would add that 'for i in {$1..$2}' works as intended in zsh. If your system has zsh installed, you can just change your shebang to zsh.

Using zsh with the example 'for i in {$1..$2}' also has the added benefit that $1 can be less than $2 and it still works, something that would require quite a bit of messing about if you wanted that kind of flexibility with a C-style for loop.

于 2014-02-04T06:44:20.763 回答