如何在 bash 中观看 for 循环?

如何在 bash 中观看 for 循环?

是否可以forwatch命令中使用 -loop ?

我不太确定如何通过我的尝试来解决此错误:

$ for i in 1 2 3; do echo $i; done
1
2
3
$ watch -n 10 for i in 1 2 3; do echo $i; done
-bash: syntax error near unexpected token `do'
$ watch for i in 1 2 3; do echo $i; done
-bash: syntax error near unexpected token `do'
$

答案1

watch命令参数是使用 运行的脚本sh -c

如果命令参数只是一个由空格分隔的标记列表(例如watch ls -l),它将它们全部连接起来并运行它们。但未加引号的 shell 元字符是watch由您运行的 shell 使用并且是从未见过watch

这意味着需要转义或引用等元字符,; & | < >以防止您运行的 shell 将watch这些字符视为标记命令结束watch、在后台运行 watch 命令或通过管道传输输出的指令进入watch另一个程序(而不是在监视脚本内运行管道)。

应用通常的引用规则 - 使用单引号来防止变量插值,否则使用双引号。 man watch最后有一个示例部分显示了这一点。

例如:

watch -n 10 'for i in 1 2 3; do echo $i; done'

或者

watch -n 10 'grep something /var/log/kern.log | tail'

注意:如果你想在watch没有.例如。-xsh -cwatch -x awk -f script.awk

答案2

您键入的命令在 shell 尝试运行之前就已由当前 shell 进行了解析watch。 shell 解释了;do因为您没有采取任何措施来保护这些内容免受 shell 的影响。do出乎意料,但首先您不希望 shell 将其解释;为命令终止符。

一般来说,您可以通过转义(例如\;)或引用(例如';')来保护事物不被 shell 解释/扩展。就您而言,您需要保护;$。但接下来有一个问题:该怎么watch办?

通常watch不只是运行命令。它运行 shell 代码,即将一些代码传递给sh -c.该代码是根据一个或多个参数编写的watch(因此例如watch echo foo工作方式类似于watch "echo foo")。

可以watch -x在没有 shell 的情况下运行命令,但是要运行for循环,您确实需要 shell。

事实上,watch当多个空格很重要并且您不小心引用时,从多个参数构建 shell 代码可能会导致错误。另一个执行类似操作的命令是ssh,您可以在中找到一些分析我的这个答案

解决所有这些问题的一种方法是使用单引号一切你想成为 shell 代码,所以watch得到正好一个包含代码的参数。在你的情况下:

watch -n 10 'for i in 1 2 3; do echo $i; done'

请注意,一般来说,代码watch运行时sh需要自己的引号,有时需要单引号那里,因此简单地用新的单引号包含整个代码可能会也可能不会。如果在当前 shell 的上下文中新的单引号与已存在的单引号配对,而不是彼此配对,则它将不起作用(或者在最好的情况下它会偶然起作用)。请参见如何在 Bash 中方便地使用单引号或转义整个命令行?。链接的问题包含通用手动解决方案;我的回答提供了一种在 Bash 中自动进行此类引用的方法。

相关内容