csh while 单行循环

csh while loop in single line

我试图打印 ping 命令的日期,以模拟与 bash ping 1.1.1.1 -O | while read pong; do echo "$(date): $pong"; done 中类似的效果,但到目前为止无法正常工作。

在 csh shell 上尝试了以下操作,但不起作用: ping 1.1.1.1 -O | while ( 1 ) echo `date` end

我错过了什么?感谢您的帮助。

您缺少的是 csh 和 tcsh 使用的语法不像 bash 和其他 Bourne 派生的 shell 所使用的语法那样通用和灵活。

csh 确实有 1 行 if 语句的特殊语法:

if (condition) statement

但它没有任何类似的 for 循环:

% while (1) echo hello
while: Expression Syntax.

并且它不允许将命令的输出通过管道输送到循环中。

如果出于某种原因你必须使用csh/tcsh,你可以编写一个脚本来封装你的while循环并将命令的输出通过管道传递给该脚本,或者您可以调用 shbash 流程来为您完成工作:

csh% bash -c 'ping 1.1.1.1 -O | while read pong; do echo "$(date): $pong"; done'

(我多年来一直使用 csh 和 tcsh,无论是交互方式还是用于脚本编写。我自己的解决方案是首先开始使用 bash 进行脚本编写,然后完全放弃 tcsh 并使用bash 作为我的默认值 shell。这是一个学习曲线,并且 一些 tcsh 功能在 [=39= 中不太方便], 但我推荐它。)

法律要求我 post 这个 link:

https://web.mit.edu/ghudson/info/csh.whynot

正如 Keith 所指出的,与 Bourne shell 相比,tcsh 在很多方面都相当有限。但是在这种特殊情况下,您可以通过将输出管道传输到例如sed 并在每一行前加上一个日期:

> ping -O 127.0.0.1 | sed "s/^/`date` /"
Sun Apr 19 14:12:28 WITA 2020 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
Sun Apr 19 14:12:28 WITA 2020 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.039 ms
Sun Apr 19 14:12:28 WITA 2020 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.057 ms
Sun Apr 19 14:12:28 WITA 2020 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.056 ms

请记住,大多数 Unix 实用程序已经在每一行上运行,因此通常不需要执行 while 循环来在每一行上运行。

谢谢Keith/Martin。是的,两个答案都一样好。

为了他人的利益:以下两者都满足我的需要,我可以从 csh/tcsh shell 中使用任何一个,实际上在任何 shell:

bash -c 'ping 127.0.0.1 -O | while read pong; do echo "$(date): $pong"; done'

ping -O 127.0.0.1 | sed "s/^/`date` /"