有没有办法在不中断输出的情况下从管道尾部命令每分钟打印时间?

时间:2014-09-06 04:48:04

标签: linux bash

我有一个很长的管道尾部命令,我在ssh上执行(例如tail -f <file>|egrep -v "lol"),通常没有太多输出,并且想要确保连接是实时的,并且希望每隔60或300秒打印一次。

4 个答案:

答案 0 :(得分:3)

你应该能够改变命令的顺序并获得date输出中的tail -f

( while : ; do date; sleep 60; done )& tail -f <file>|egrep -v "lol"; kill %1

注意:您正在处理每60秒提供一次日期的过程,因此您需要在完成后kill %1终止后台作业。如果您有多个进程后台,则需要捕获作业号。我尝试过使用syslog,它似乎有效。如果它适用于您的情况,请回报。

答案 1 :(得分:1)

尝试:

tail -f file | perl -ne 'BEGIN{$|=1} print unless /lol/'

当然,如果您只想打印时间戳,请尝试:

tail -f file | { while sleep 60; do date; done& grep -v lol; }

答案 2 :(得分:0)

将这样的小脚本添加到管道的末尾:

#!/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 date可以避免SECONDS的执行:

#!/bin/bash
last=$SECONDS
while : ; do
    read -t 10 line && [[ $? -eq 0 ]] && last=$SECONDS && echo $line
    [[ $(($SECONDS-last)) -ge 60 ]] && last=$SECONDS && date
done

答案 3 :(得分:0)

或者,略有不同的方法......制作一个FIFO并在那里发送原始管道的输出,并将其拖尾,但在后台,还有一个小循环,每分钟也会向FIFO发送一次时间戳。像这样(未经测试)

mkfifo FIFO
original_pipe | ... | ... > FIFO &

现在每隔60秒向FIFO注入一个时间戳:

while :; do date > FIFO; sleep 60; done &

现在只需拖尾FIFO

tail -F FIFO