我试图获取 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
我缺少什么?感谢您的帮助。
正如 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
循环来在每一行上运行。
您缺少的是 csh 和 tcsh 使用的语法并不像 bash 和其他 Bourne 派生 shell 使用的语法那么通用和灵活。
csh 确实有 1 行
if
语句的特殊情况语法:
if (condition) statement
但它没有任何类似的 for 循环:
% while (1) echo hello
while: Expression Syntax.
并且它不允许将命令的输出传送到循环中。
如果出于某种原因必须使用csh/tcsh,您可以编写一个脚本来封装您的
while
循环并将命令的输出通过管道传输到该脚本,或者您可以调用sh
或bash
进程来执行适合您的工作:
csh% bash -c 'ping 1.1.1.1 -O | while read pong; do echo "$(date): $pong"; done'
(我多年来一直使用 csh 和 tcsh,无论是交互方式还是用于脚本编写。我自己的解决方案是首先开始使用 bash 进行脚本编写,然后完全放弃 tcsh 并使用 bash 作为我的默认 shell。这是一个有点学习曲线,并且有一些 tcsh 功能在 bash 中不太方便,但我推荐它。) 法律要求我发布此链接:
https://web.mit.edu/ghudson/info/csh.whynot为了他人的利益:以下两者都满足了我的需要,我可以从 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` /"
mkfifo ~/fifo
echo 'while 1\
set pong = "$<"\
echo "`date`: $pong"\
end' > ~/fifo & ping -O 1.1.1.1 | ( source ~/fifo )