Reputation: 1693
As part of a bash script, I want to run a program repeatedly, and redirect the output to less
. The program has an interactive element, so the goal is that when you exit the program via the window's X button, it is restarted via the script. This part works great, but when I use a pipe to less
, the program does not automatically restart until I go to the console and press q
. The relevant part of the script:
while :
do
program | less
done
I want to make less
quit itself when the pipe closes, so that the program restarts without any user intervention. (That way it behaves just as if the pipe was not there, except while the program is running you can consult the console to view the output of the current run.)
Alternative solutions to this problem are also welcome.
Upvotes: 1
Views: 1056
Reputation: 11
You may try to kill the process group program
and less
belong to instead of using kill
and 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
Upvotes: 1
Reputation: 531798
Instead of exiting less
, could you simply aggregate the output of each run of program
?
while :
do
program
done | less
Having less
exit when program
would be at odds with one useful feature of less
, which is that it can buffer the output of a program that exits before you finish reading its output.
UPDATE: Here's an attempt at using a background process to kill less
when it is time. It assumes that the only program reading the output file is the less
to kill.
while :
do
( program > /tmp/$$-program-output; kill $(lsof -Fp | cut -c2-) ) &
less /tmp/$$-program-output
done
program
writes its output to a file. Once it exits, the kill
command uses lsof
to
find out what process is reading the file, then kills it. Note that there is a race condition; less
needs to start before program
exists. If that's a problem, it can
probably be worked around, but I'll avoid cluttering the answer otherwise.
Upvotes: 5
Reputation: 37298
While I agree with chepner's suggestion, if you really want individual less
instances, I think this item for the man page will help you:
-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.
you would make this option visible to less in the LESS
envir variable
export LESS="-E"
while : ; do
program | less
done
IHTH
Upvotes: 0