关于linux:如何在bash for循环中使用变量

How to use variables in a bash for loop

本问题已经有最佳答案,请猛点这里访问。

如何在bash for循环中使用变量?
如果我只是使用标准for循环,它会做我期望的

1
2
3
4
for i in {0..3}
do
   echo"do some stuff $i"
done

这很好用。 它循环4次,0到3次,打印我的消息并将计数结束。

1
2
3
4
do some stuff 0
do some stuff 1
do some stuff 2
do some stuff 3

当我尝试使用以下for循环时,它似乎等于一个字符串,这不是我想要的。

1
2
3
4
5
length=3
for i in {0..$length}
do
   echo"do something right $i"
done

输出:

1
do something right {0..3}

我试过了

1
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3})

1
for i in {0..'$length'} (output was {0..$length})

他们都不做我需要的事。 希望有人可以帮助我。 在此先感谢任何bash专家对for循环的帮助。


一种方法是使用eval

1
2
3
4
for i in $( eval echo {0..$length} )
do
       echo"do something right $i"
done

请注意当您设置length=;lslength=; rm *时会发生什么(尽管不要尝试后者)。

安全地,使用seq

1
2
3
4
for i in $( seq 0 $length )
do
       echo"do something right $i"
done

或者你可以使用c风格的循环,这也是安全的:

1
2
3
4
for (( i = 0; i <= $length; i++ ))
do
       echo"do something right $i"
done


在bash中,大括号扩展是第一步尝试,因此,$length将不会被替换。

bash的联机帮助页明确指出:

A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters ...

有许多可能性,例如使用:

1
2
3
4
5
pax> for i in $(seq 0 $length) ; do echo $i ; done
0
1
2
3

虽然如果length很大,这可能会给你一个大的命令行。

另一种方法是使用类C语法:

1
2
3
4
5
pax> for (( i = 0; i <= $length; i++ )) ; do echo $i; done
0
1
2
3


Brace替换在任何其他之前执行,因此您需要使用eval
seq这样的第三方工具。

评估示例:

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

实际上可以在man bash中找到此信息:

A sequence expression takes the form {x..y[..incr]}, where x and y are either
integers or single characters, and incr, an optional increment, is an integer.
[...]

Brace expansion is performed before any other expansions, and any characters special
to other expansions are preserved in the result. It is strictly textual.
Bash does not apply any syntactic interpretation to the context of the expansion
or the text between the braces.