作为bash脚本的一部分,我想重复运行一个程序,并将输出重定向到less
。该程序具有交互元素,因此目标是当您通过窗口的X按钮退出程序时,它将通过脚本重新启动。这部分效果很好,但当我使用管道less
时,程序不会自动重启,直到我进入控制台并按q
。脚本的相关部分:
while :
do
program | less
done
我想在管道关闭时让less
自行退出,这样程序就可以在没有任何用户干预的情况下重新启动。 (这样它的行为就像管道不存在一样,除非程序运行时你可以咨询控制台查看当前运行的输出。)
也欢迎这个问题的替代解决方案。
答案 0 :(得分:4)
您是否可以简单地汇总less
每次运行的输出,而不是退出program
?
while :
do
program
done | less
当less
与program
的一个有用功能不一致时,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)
您可以尝试终止属于program
和less
的流程群,而不是使用kill
和lsof
。
#!/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