在bash中,是否可以在for循环的循环控制中使用整数变量?


65

我有以下bash脚本:

#!/bin/bash

upperlim=10

for i in {0..10}
do
echo $i
done

for i in {0..$upperlim}
do
echo $i
done

第一个for循环(在循环控制中没有变量upperlim)可以正常工作,但是第二个for循环(在循环控制中具有变量upperlim)不能正常工作。有什么方法可以修改第二个for循环以使其起作用?谢谢你的时间。


4
嗯,甚至for i in {0..$((upperlim))}; do echo $i; done都不起作用
Bonsi Scott

和+1,因为我发现这种行为很有趣
Bonsi Scott 2012年


回答此问题的外部链接:cyberciti.biz/faq/…–
kon psych

Answers:


62

其原因是bash中事物发生的顺序。括号扩展发生变量被扩展之前。为了实现您的目标,您需要使用C样式的for循环:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done

1
而工程zsh以及(但不适合cshtcsh)。
数学

29

要使用您的样式来完成此任务,而只使用内置插件,则必须使用eval:

d=12

for i in `eval echo {0..$d}`
do
echo $i
done

但是用seq

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

我个人认为使用seq更具可读性。


对于“内置”?seq是一个外部命令,并非在所有bash上都可用。
jordanm 2012年

9
@jordanm:用于在bash中使用所有内置函数。然后我说“但是seq”,并承认它不是内置的。
朱迪·C

括号扩展内置的事实在这里不是问题。read例如是内置的,但没有理由eval
jordanm 2012年

1
内置文件根本没有问题。我想为问询者提供全力以赴的解决方案。如果您想继续争论,可以聊天。评论对这种事情不是很好
Jodie C

8

POSIX方式

如果您关心可移植性,请使用POSIX标准中示例

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

输出:

2
3
4
5

事情是不是 POSIX:


1

您的方法将不起作用,因为在bash中,在参数扩展之前进行了括号扩展。您需要先扩展变量。

您可以使用eval解决

upperlim=10
eval '
        for i in {0..'"$upperlim"'}
        do
                echo $i
        done
'

使用While循环

upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
    echo "$start"
    ((start = start + 1))
done

您也可以使用seq命令执行此操作

upperlim=10
#seq
for i in $(seq "$upperlim"); do
  echo "$i"
done

如果要与for i in {0..$upperlim}您一起运行,则需要使用kornshell。例如:

#!/bin/ksh
upperlim=10

for i in {0..$upperlim}
do
        echo $i
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.