管道关闭时退出

时间:2014-02-07 19:59:58

标签: bash

作为bash脚本的一部分,我想重复运行一个程序,并将输出重定向到less。该程序具有交互元素,因此目标是当您通过窗口的X按钮退出程序时,它将通过脚本重新启动。这部分效果很好,但当我使用管道less时,程序不会自动重启,直到我进入控制台并按q。脚本的相关部分:

while :
do
    program | less
done

我想在管道关闭时让less自行退出,这样程序就可以在没有任何用户干预的情况下重新启动。 (这样它的行为就像管道不存在一样,除非程序运行时你可以咨询控制台查看当前运行的输出。)

也欢迎这个问题的替代解决方案。

3 个答案:

答案 0 :(得分:4)

您是否可以简单地汇总less每次运行的输出,而不是退出program

while :
do
    program
done | less

lessprogram的一个有用功能不一致时,less退出,这是因为它可以缓冲在读完输出之前退出的程序的输出


更新:这是尝试使用后台进程在时间过后杀死less。它假定读取输出文件的唯一程序是要杀死的less

while :
do
    ( program > /tmp/$$-program-output; kill $(lsof -Fp | cut -c2-) ) &
    less /tmp/$$-program-output
done

program将其输出写入文件。退出后,kill命令使用lsof 找出正在读取文件的进程,然后将其杀死。请注意,存在竞争条件; less需要在program存在之前启动。如果这是一个问题,它可以 可能会被解决,但我会避免使答案混乱。

答案 1 :(得分:1)

您可以尝试终止属于programless的流程群,而不是使用killlsof

#!/bin/bash

trap 'kill 0' EXIT

while :
do
   # script command gives sh -c own process group id (only sh -c cmd gets killed, not entire script!)
   # FreeBSD script command
   script -q /dev/null sh -c '(trap "kill -HUP -- -$$" EXIT; echo hello; sleep 5; echo world) | less -E -c'
   # GNU script command
   #script -q -c 'sh -c "(trap \"kill -HUP -- -$$\" EXIT; echo hello; sleep 5; echo world) | less -E -c"' /dev/null
   printf '\n%s\n\n' "you now may ctrl-c the program: $0" 1>&2
   sleep 3
done

答案 2 :(得分:0)

虽然我同意chepner的建议,如果你真的想要个人less个实例,我认为该手册页的这个项目可以帮助你:

   -e or --quit-at-eof
          Causes less to automatically exit the second time it reaches end-of-file.  By  default,
          the only way to exit less is via the "q" command.

   -E or --QUIT-AT-EOF
          Causes less to automatically exit the first time it reaches end-of-file.

您可以在LESS envir变量

中将此选项显示为更少
export LESS="-E"
while : ; do
    program | less
done

IHTH