单行Bash无限while循环的语法


633

我在提出分号和/或花括号的正确组合时遇到了麻烦。我想这样做,但是作为命令行的单行代码:

while [ 1 ]
do
    foo
    sleep 2
done

4
用分号替换换行符。对于for循环同样适用。
汤姆”,

23
@Tom:并不总是有效。完成之后,您必须有第一个命令,而不是分号
Stefano Borini

Answers:


1230
while true; do foo; sleep 2; done

顺便说一句,如果您在命令提示符下将其键入为多行(如显示),然后使用向上的箭头调用历史记录,则可以将其放在一行中并正确标点。

$ while true
> do
>    echo "hello"
>    sleep 2
> done
hello
hello
hello
^C
$ <arrow up> while true; do    echo "hello";    sleep 2; done

2
“如果在命令提示符下将其键入为多行(如图所示),然后使用向上的箭头调用历史记录,则会在一行上正确地标出它。” 对我来说不是真的。
文森特·沙伊布

@VincentScheib,检查cmdhist选项是否正在使用bash?
Alok Singhal 2013年

优秀的!在Mavericks(Mac OS-X 10.9)上完美运行,并允许我保持vpn的运行。几个小时后,Openconnect断开连接,并出现严重的Cookie错误。因此,我将openconnect命令放入shell脚本sudo su中,成为root用户,并使用以下cmd行: while true; do sh /Users/myuser/bin/vpn ; done
Blisterpeanuts

170

也可以在while条件下使用sleep命令。使单线看起来更干净恕我直言。

while sleep 2; do echo thinking; done

16
嗯,这不仅仅是更改语法,它还可以在睡眠执行命令。在上一个答案中,命令立即执行。只是要注意。
DanGordon '16

@DanGordon while echo thinking ; do sleep 2 ; done 当然,如果[while]命令失败,则循环将退出,因此您必须这样做while echo thinking || true ; do sleep 2 ; done,然后您将返回while true ; ...
Brian Carcich

69

冒号始终是“ true”:

while :; do foo; sleep 2; done

15
为什么冒号总是正确的?
尔根·保罗(

8
@Pineapple Under the Sea:在bash手册页上:(在SHELL BUILTIN COMMANDS部分中) : [arguments] 无效;该命令除了扩展参数和执行任何指定的重定向外,什么也不做。返回零退出代码。
Adrian W

2
推荐使用此语法,因为:是shell本身的一部分,即:是shell内置命令。
avner 2014年

@analytik所以您是说这是一个加号或减号?;-)
Brian Carcich

33

您可以使用分号来分隔语句:

$ while [ 1 ]; do foo; sleep 2; done

3
我喜欢这个答案,因为它解释了何时以及为什么;(分号)为必填项。
AndreasGeo先生17年

29

您还可以使用以下until命令:

until ((0)); do foo; sleep 2; done

请注意,与相比whileuntil只要测试条件的退出状态不为零,就可以在循环内执行命令。


使用while循环:

while read i; do foo; sleep 2; done < /dev/urandom

使用for循环:

for ((;;)); do foo; sleep 2; done

另一种使用方式until

until [ ]; do foo; sleep 2; done

until ((0)); do foo; sleep 2; done似乎没有工作时。它连续无限。
030

11

一个非常简单的无限循环.. :)

while true ; do continue ; done

如果您的问题是:

while true; do foo ; sleep 2 ; done

8

我喜欢只对WHILE语句使用分号,并且&&运算符使循环执行不只一件事...

所以我总是这样

while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done

1
嗯,&&在循环中的使用与其他时间完全相同,不是吗?您是否仅在第一件事发生时才需要第二件事发生,然后使用&&else ;就足够了。确实,您希望使该循环的内容简短而简单,理想情况下,只需一个命令,即一个函数或一个脚本即可。
thecoshman


6

使用while

while true; do echo 'while'; sleep 2s; done

使用for循环:

for ((;;)); do echo 'forloop'; sleep 2; done

使用Recursion,(与上面稍有不同,键盘中断不会停止它)

list(){ echo 'recursion'; sleep 2; list; } && list;

5

如果您希望while循环在某些条件后停止,并且您的foo命令在满足此条件时返回非零值,则可以使循环中断,如下所示:

while foo; do echo 'sleeping...'; sleep 5; done;

例如,如果foo命令正在批量删除事物,并且在没有什么要删除的情况下返回1。

如果您有一个自定义脚本,该脚本需要多次运行命令直到出现某种情况,则此方法很好用。您编写脚本以1在满足条件0时退出,并在应再次运行时退出。

例如,假设您有一个python脚本batch_update.py,该脚本将更新数据库中的100行,并0在有更多要更新的内容时(1如果没有)进行更新。以下命令将允许您一次更新行100,两次更新之间应休眠5秒钟:

while batch_update.py; do echo 'sleeping...'; sleep 5; done;

您将如何退出?
AK_18年

当您希望while循环中断时,可以foo使用代码使命令退出1。我用一个例子更新了我的答案。
Yep_It's_Me

2

如果我可以举两个实际的例子(有点“情感”)。

这会将所有以“ .jpg”结尾的文件的名称写入文件夹“ img”中:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done

这将删除它们:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done

只是想贡献。


1
@JKnight -对于这些例子,你会不会只是做ls -1 *.jpgrm *.jpg
凯文·费根

2
两者都不是无限循环,也不是while循环。
玛丽安2015年

2

您也可以尝试这样做。警告:您不应该这样做,但是由于问题是要求无限循环,这是您可以做到的。

while [[ 0 -ne 1 ]]; do echo "it's looping";   sleep 2; done

你为什么还要这么做?
gniourf_gniourf

2
因为发布问题的Brian Deacon希望像一个无限循环。这不仅是为猫全部
皮毛的
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.