10

Often times I find myself in need to have the output in a buffer with all the features (scrolling, searching, shortcuts, ...) and I have grown accustomed to less.

However, most of the commands I use generate output continuously. Using less with continuous output doesn't really work the way I expected.

For instance:

while sleep 0.5
do
    echo "$(cat /dev/urandom | tr -cd 'a-zA-Z0-9' | head -c 100)"
done | less -R

This causes less to capture the output until it reaches maximum terminal height and at this point everything stops (hopefully still accepting data), allowing me to use movement keys to scroll up and down. This is the desired effect.

Strangely, when I catch-up with the generated content (usually with PgDn) it causes less to lock and follow new data, not allowing me to use movement keys until I terminate with ^C and stop the original command. This is not the desired effect.

Am I using less incorrectly? Is there any other program that does what I wish? Is it possible to "unlock" from this mode?

Thank you!

6

Works OK for me when looking at a file that's being appended to but not when input comes from a pipe (using the F command - control-C works fine then).

See discussion at Follow a pipe using less? - this is a known bug/shortcoming in less.

0
6

Is there any way to exit “less” follow mode without ^C?

Yes, starting from version 569 one can exit follow mode with CTRL+X which does not stop other processes in a pipe.

For earlier versions of less (supporting only CTRL+C) one can arrange things so that SIGINT signal which is being sent when pressing CTRL+C does not effect other processes in a pipe thus allowing them to continue running. This can be achieved by doing any of the following:

  • preventing SIGINT from reaching other processes in a pipe by moving these processes into a separate process group using setsid utility:

(setsid seq 10000000) | less +F

  • handling (catching) SIGINT so that it does not get delivered to other processes in a pipe:

(trap '' INT; seq 10000000) | less +F

  • using process substitution (non POSIX feature, implemented in Bash, Zsh and Ksh but not in e.g. Dash):

less -f +F <(seq 10000000)

(seq 10000000 &) | less +F

To observe effects of above commands on process groups and signal handling I suggest using ps -O ppid,pgrp,sid,ignored --forest -C bash,less,seq command in a separate terminal.

4
1

Maybe the simplest answer:

trap '' INT
your_input_pipeline | less +F
# you may want to restore or define new INT trap here
echo still in the shell

This also prevents the enclosing shell from being interrupted which can happen with other answers, if the shell is not Bash.

1
( your_input_pipeline & ) | less +F

and

{ your_input_pipeline & } | less +F

seem to work in Bash. It works also in Zsh and Dash except that the INT signal propagates to the enclosing shell after less exits. Does not work in Ksh.

Test configuration:

GNU bash 5.0.17
dash 0.5.10.2-6 (package version in Ubuntu Linux)
zsh 5.8
less 551
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.