我想定期执行一个程序并观察何时发生变化。听起来 watch 是正确的命令,但它会打印出令人讨厌的空行,这使得我们无法查看历史记录。开关-t
在这里并没有真正的帮助。
我想要的是:
user@machine ~$ #some previous command
user@machine ~$ watch -t date -Is
2020-10-09T12:50:13
2020-10-09T12:50:15
2020-10-09T12:50:17
我得到什么:
2020-10-09T12:50:17
(之前的所有行都消失了)。
我知道我可以使用 while 循环和 sleep 命令,但这需要更长的时间来输入,并且还有其他缺点。这个循环:while true; do date -Is ; sleep 2; done
有效,但我更喜欢一个简单的命令。我还读到了有关使用 tee 的技巧,就像这样watch -t ' date -Is | tee -a ./somefile
,但这对我来说并不总是一个可行的解决方案,因为这只适用于可写文件系统,如果它是临时文件系统,我在重新启动后无法读取它,这是一个问题一个嵌入式系统,有时我没有安装可写文件系统,并且在崩溃/重新启动后无法读取 tempfs。
我还尝试用 grep: 过滤掉空行,watch -t date -Is | grep -v '^$'
但后来我没有输出。
答案1
有点复杂,但你可以这样做:
yes 'date -Is' | pv -qlL1 | sh
(还有每秒运行一次命令的优点,而不是每 2 秒加上运行它所需的时间)
1
以上是每秒行数的速率,只能是整数。所以每秒 1 次是您能达到的最慢速度。您可以删除,-l
但在这种情况下,费率将以数量为单位字节每秒。因此,如果每行 9 个字节,则每 9 秒就有一个命令。
答案2
perl -e '$t=shift; while(1){print $o=$n if ($n=qx(@ARGV)) ne $o; sleep $t}' 1 date -Is
2020-10-07T06:49:07+03:00
2020-10-07T06:49:08+03:00
2020-10-07T06:49:09+03:00
2020-10-07T06:49:10+03:00
改进的版本,可以进行分数延迟并正确处理命令和参数中的空格和特殊字符:
#! /usr/bin/perl
use Time::HiRes qw(sleep);
die "usage: $0 delay cmd [args ...]\n" if @ARGV < 2;
sub slurpcmd {
open my $h, '-|', @_ or die "open $_[0]|: $!";
local $/ unless wantarray;
<$h>
}
my $t = shift; my ($o, $n);
while(1){print $o=$n if ($n=slurpcmd @ARGV) ne $o; sleep $t}
添加选项来格式化命令的输出(如果是多行等,则将其很好地分开)留给读者作为练习;-)