`docker logs foo | less` isn’t searchable or scrollable but `docker logs foo 2>&1 | less` is

lesspipestderrstdout

Using either one gives readable text. But only with the stderr redirect can one scroll or type /somepattern and get matches.

Without it searching gives "Nothing to search (press RETURN)" and a column of ~'s.

Given, stderr and stdout aren't the same but why does less show them the same right up until I start doing something in less?

This maybe some weird multi-window vim thing that I just don't understand. Thoughts?

Best Answer

+--------------------+        +------+       +----------+
|             stdout |·······→| less |——————→|          |
| somecommand        |        +------+       | terminal |
|             stderr |——————————————————————→|          |
+--------------------+                       +----------+

If somecommand prints text to standard error only, then when you run somecommand | less, somecommand and less are both displaying to the terminal. The output of the command on its stderr isn't going to less, it's going to the terminal directly, since it isn't redirected. First the output of somecommand scrolls by while less initializes and shows its prompt line; then when somecommand finishes less notices that its input is complete (because the pipe is closed). You may want to experiment a bit: run

{ sleep 1; somecommand; sleep 1; } | { sleep 0; less; }

and variations on the sleep times to have somecommand produce output before or after less is ready and to see what happens when the pipe is closed.

Related Question