ChatGPT解决这个技术问题 Extra ChatGPT

Bash 中单行 while 循环的语法

我无法想出正确的分号和/或大括号组合。我想这样做,但作为命令行的单行代码:

while [ 1 ]
do
    foo
    sleep 2
done
用分号替换换行符。对于 for 循环也是如此。
@Tom:这并不总是有效。在do之后,你必须有第一个命令,而不是分号

S
Stefano Borini
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

“如果您在命令提示符下将其键入为多行(如您所显示的那样),然后使用向上箭头调用历史记录,您将在单行上得到正确的标点。”对我来说不是这样。
@VincentScheib,如果您使用的是 bash,请检查 cmdhist 选项?
出色的!在 Mavericks (Mac OS-X 10.9) 上完美运行,并允许我保持 vpn 运行。几个小时后,Openconnect 会因 cookie 错误而断开连接。所以我把 openconnect 命令放在一个 shell 脚本中,sudo su 成为 root,并使用这个 cmd 行:while true; do sh /Users/myuser/bin/vpn ; done
A
Anssi

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

while sleep 2; do echo thinking; done

好吧,这不仅仅是改变语法——它会在睡眠后执行命令。在上一个答案中,该命令立即执行。只是需要注意的一点。
@DanGordon while echo thinking ; do sleep 2 ; done 当然,如果 [while] 命令失败,循环退出,所以你必须 while echo thinking || true ; do sleep 2 ; done 但你又回到 while true ; ...
a
ajaaskel

冒号总是“真”:

while :; do foo; sleep 2; done

为什么冒号总是正确的?
@Pineapple Under the Sea:来自 bash 手册页:(在 SHELL BUILTIN COMMANDS 部分): [arguments] 无效;该命令除了扩展参数和执行任何指定的重定向之外什么都不做。返回零退出代码。
这种语法被推荐为:是shell本身的一部分,即:是一个shell内置命令。
m
mipadi

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

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

我喜欢这个答案,因为它解释了何时以及为什么; (分号)是必需的。
d
devnull

您还可以使用 until 命令:

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

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

使用 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 似乎不起作用。它连续无限。
M
Muhammad Soliman

使用 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;

小心使用 sleep 中的单位,例如 sleep 1h。在我的 zsh 中,它忽略单位 h 并每 1 秒运行一次我的命令。快速执行 man sleep 以首先查看您的环境的 sleep 命令支持什么。可能会让你头疼。
P
Peter Mortensen

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

while true ; do continue ; done

你的问题是:

while true; do foo ; sleep 2 ; done

u
user000001

对于简单的过程监视,请改用 watch


D
DanielGibbs

我喜欢只在 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

好吧,在循环中使用 && 与其他任何时候一样,真的不是吗。只有当第一件事发生时,您才需要第二件事发生,然后使用 && else ; 就足够了。确实,您希望保持该循环的内容简短而简单,理想情况下只有一个命令,一个函数或一个脚本。
小心使用 sleep 中的单位,例如 sleep 1h。在我的 zsh 中,它忽略单位 h 并每 1 秒运行一次我的命令。快速执行 man sleep 以首先查看您的环境的 sleep 命令支持什么。可能会让你头疼。
这次真是万分感谢。我一直在寻找在“做”中运行不止一件事的正确方法
Y
Yep_It's_Me

如果您希望 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;

你将如何退出?
当您希望 while 循环中断时,您可以使用代码 1 退出 foo 命令。我已经用一个例子更新了我的答案。
V
Victor Yarema

您甚至不需要使用 dodone。对于无限循环,我发现将 for 与花括号一起使用更具可读性。例如:

for ((;;)) { date ; sleep 1 ; }

这适用于 bashzsh。在 sh 中不起作用。


R
Roger

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

这会将所有以“.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

只是想做出贡献。


@JKnight - 对于这些例子,你不会只做 ls -1 *.jpgrm *.jpg
两者都不是无限循环,也不是 while 循环。
g
grepit

你也可以试试这个警告:你不应该这样做,但因为问题是要求无限循环......这就是你可以做到的。

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

你为什么还要这样做?
因为发布问题的布赖恩·迪肯(Brian Deacon)想要一个无限循环。给猫剥皮的方法不止一种
为什么你不应该?
m
michal-michalak

您还可以将该循环放在后台(例如,当您需要与远程机器断开连接时)

nohup bash -c "while true; do aws s3 sync xml s3://bucket-name/xml --profile=s3-profile-name; sleep 3600; done &"