如何从管道中以 **less** (`+F`) 终止 _follow_ 模式?

如何从管道中以 **less** (`+F`) 终止 _follow_ 模式?

假设 bash 中有以下虚拟命令:

### dummy long_operation_cmd function, for easy reproduction:
function long_operation_cmd() {
  echo "operation 1"
  sleep 5
  echo "operation 2"
}

我目前正在按以下方式运行 bash 脚本:

{
    long_operation_cmd
    echo '===ALL DONE==='
} > /tmp/logfile.tmp &
tail -f /tmp/logfile.tmp | sed '/^===ALL DONE===$/ q' \
&& rm /tmp/logfile.tmp

这使我能够在后台安全地运行长操作,跟踪输出,并确保 Ctrl+C 不会中断执行。

最重要的是,当操作完成后,sed让我摆脱跟随模式。

我想替换tail -fless +F,这就是我想出的:

{
    long_operation_cmd
    echo '===ALL DONE==='
} > /tmp/logfile.tmp &
less +F -- /tmp/logfile.tmp \
&& rm /tmp/logfile.tmp

===ALL DONE===但是,我无法找到一种方法来在达到模式时(或long_operation_cmd操作完成时)自动摆脱跟随模式。

关于解决这个问题有什么建议吗?

答案1

当“ALL DONE”时,您可以向进程发送 SIGINT 信号:

kill -int PID

不过,这需要您知道 PID(less +F也在后台运行?)。

答案2

看来我要走一条不同的路了。

我将tail -f首先捕获 Ctrl-C,然后再减少。如果一切顺利,我不会运行less,但如果tail“失败”(这是使用 Ctrl+C 的情况),我将启动 less - 如果需要,我可以在 less 中继续使用“F”。

最终结果将如下所示:

{
    long_operation_cmd
    echo '===ALL DONE==='
} > /tmp/logfile.tmp &
(trap : INT; tail -f /tmp/logfile.tmp | sed '/^===ALL DONE===$/ q' ) \
|| less +G /tmp/logfile.tmp && rm /tmp/logfile.tmp

相关内容