17

I often pipe program output to less, e.g.

produce_output | less

This works great, until produce_output produces large amounts of output. If I search for some text that is deep into the file, less reports

Calculating line numbers... (interrupt to abort)

If I interrupt with Control+C, it also kills produce_output, which stops it from producing further output. Is there any way to send the interrupt to less, so that produce_output keeps running?

I know that I could use kill -INT less_process, but I think there must be a better solution.

1

4 Answers 4

21

Normally all processes in a pipeline run in the same process group, causing all of them to receive the signal. You can use setsid foo | less to run foo in a different pgrp.

6
  • It light of the problem raised by OP it seems that decision to use CTRL+C as a way to interrupt less is very unfortunate. Do you know why this specific signal was chosen? Would some other signal be less problematic? Jan 21, 2015 at 11:21
  • @PiotrDobrogost: What other signal would you suggest? There aren't many that have dedicated keyboard shortcuts, only SIGINT (Ctrl-C) and SIGQUIT (Ctrl-\), and the latter is meant to exit the program immediately, not merely interrupt. The rest are only available via kill. Jan 21, 2015 at 11:28
  • It seems that the problem is caused by using signal to interrupt less. Instead, if it were some normal key/shortcut we wouldn't have the problem in the first place. However I guess the need for a signal comes from the fact that process can't use select to wait for input both from a file/pipe and terminal at the same time. Jan 21, 2015 at 12:49
  • @PiotrDobrogost: It can, that's how the F (follow) mode works. Pipes and ttys are pollable the same way. Jan 21, 2015 at 13:10
  • Why do you think that's the way follow mode works? I think the flow of events is that shell gets CTRL+C and sends SIGINT signal to less which gets this signal asynchronously without listening to keyboard/terminal. Jan 21, 2015 at 15:58
10

You can disable line numbers with the

   -n or --line-numbers

option.

produce_output | less -n
4
  • 1
    -1: may solve OP's instigating problem, but does nothing to answer OP's actual question (i.e., interrupting a process).
    – goldPseudo
    May 10, 2012 at 0:15
  • 2
    Sorry but starting less with a feature that is not wanted and then try to send a signal to disable a feature you can disable with a switch is a workaround and not a solution. Of course @grawity solution is nice (and I up voted it) but come on: starting the first process in another group to be able to send a signal to interrupt a task (line counting) that is not needed is really a little bit too much work.
    – Matteo
    May 10, 2012 at 5:26
  • 1
    This is a fair solution to the problem I posed in my question. However, interrupts stop more than just the line counting in less -- for instance, they will interrupt a long search too. So, @grawity's solution is preferred, since it would cover any use of interrupts in less. My bad for not addressing this more clearly in the question!
    – Ed McMan
    May 10, 2012 at 13:38
  • @EdMcMan Sure I also up voted gravity's solution and I happy to learn something new that can always be useful.
    – Matteo
    May 10, 2012 at 13:59
2

You can also just do this:

less +F -f <(produce_output)
1
  • Simple solution and works fine! The -f flag is important to read from the temporary pipe created.
    – Spidey
    May 21, 2020 at 18:03
0

In working with large amounts of output, I've found it very helpful to send the output to a file and use tail -f or less +F to watch, e.g.:

produce_output > out 2>&1 & less +F out

The 2>&1 syntax makes sure that both stdout and stderr go to out---remove that if you only want stdout going to the file. This way, you can inspect the output in various ways (even from a different machine) without having to mess with the program producing the output.

Note that 2>&1 may be bash-specific (I'm not sure). Be sure that you have sufficient disk space for the output file :-)

7
  • Tail will just show you the file, Ed specified that he is using less interactively (e.g., he has to search in the file)
    – Matteo
    May 9, 2012 at 15:03
  • 1
    2>&1 is POSIX, bare >& is a bashism. May 9, 2012 at 15:17
  • FWIW, 2>&1 also works on Windows XP, 7, 2008, etc.
    – jftuga
    May 9, 2012 at 16:05
  • @Matteo: yes, I should have used less +F in my example; I just updated my answer.
    – jrennie
    May 9, 2012 at 22:10
  • 1
    @Matteo: Line counting is not the same issue with less +F (since less +F processes the data as it is generated). The example I gave does not have the same problem as originally posted: ctrl+c will not interrupt process_output. If one doesn't care for the 'follow' functionality, one can run produce_output > out 2>&1, then less out. A problem with produce_output | less is that if anything breaks the pipe (e.g. accidentally hitting 'q' from less), then produce_output will die (without special SIGPIPE handling).
    – jrennie
    May 10, 2012 at 2:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .