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
    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!


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.

| improve this answer | |
  • Ah, that workaround is something I have been unintentionally using for one of my commands although I haven't managed to connect the dots :D – normalra Apr 19 '15 at 10:21

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

No, but you can arrange things so that CTRL-C does not effect other processes in the pipe thus allowing them to run.

Solution A – moving less into its own process group using monitor mode of shell (set -m)

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

Idea comes from PSkocik and was given in his answer.

Solution B – handling SIGINT (CTRL-C) so that it does not get delivered to other processes in pipe

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

Solution given by geirha on #bash IRC channel.

| improve this answer | |

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.