我有一个通过ssh
(例如tail -f <file>|egrep -v "lol"
)执行的长尾命令,通常没有太多输出,我希望确保连接是实时的,并希望每60或300秒打印一次时间。
您应该能够改变命令的顺序,并在tail -f
输出中获得date
:
( while : ; do date; sleep 60; done )& tail -f <file>|egrep -v "lol"; kill %1
注意:您正在备份每60秒提供一次日期的进程,因此您需要在完成kill %1
时终止备份作业。如果您有多个后台进程,则需要获取作业编号。我试过使用syslog,它似乎有效。如果它在你的情况下有效,请报告。
尝试:
tail -f file | perl -ne 'BEGIN{$|=1} print unless /lol/'
当然,如果你只是想打印时间戳,可以试试:
tail -f file | { while sleep 60; do date; done& grep -v lol; }
在管道末端附加一个类似的小脚本:
#!/bin/bash
while : ; do
# Read input with timeout
read -t 10 line
# Output if we got anything and remember current time in "last"
[[ $? -eq 0 ]] && last=$(date +%s) && echo $line
# Check if we are due a timestamp and output if required
now=$(date +%s)
diff=$((now-last))
[[ $diff -ge 60 ]] && last=$(date +%s) && date
done
它从stdin
读取,超时时间为10秒。如果数据源源不断,它就会不断打印。每次进行某些输出时,它都会使用上次输出的时间更新变量last
。然后,每次它都会检查在过去60 seonds中是否有任何输出,如果没有,则输出当前时间。
将上面的内容保存在一个名为monitor
的文件中,然后使其可执行(仅一次)并运行如下:
chmod +x monitor
yourpipe ...| ... | ./monitor
它可以缩写为以牺牲一些清晰度为代价,比如这样。此外,可以通过使用内置的bash SECONDS
来避免date
的exec:
#!/bin/bash
last=$SECONDS
while : ; do
read -t 10 line && [[ $? -eq 0 ]] && last=$SECONDS && echo $line
[[ $(($SECONDS-last)) -ge 60 ]] && last=$SECONDS && date
done
或者,稍微不同的方法。。。制作一个FIFO,并将原始管道的输出发送到那里,然后跟踪它,但在后台,有一个小循环,也会每分钟向FIFO发送一次时间戳。像这样的东西(未经测试)
mkfifo FIFO
original_pipe | ... | ... > FIFO &
现在每60秒向FIFO中注入一个时间戳:
while :; do date > FIFO; sleep 60; done &
现在只跟踪FIFO
tail -F FIFO