假设 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 -f
为less +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