Skip to content

Pipes and streams

12 min

Three separate things

stdin, stdout and stderr, and why a pipe only carries one of them.

Every command has three streams open: input, output, and errors. They look identical in a terminal because they both land on your screen, which is exactly why the distinction is easy to miss until it matters.

A pipe carries standard output only. Errors go straight past it to the terminal, which is why a broken pipeline still shows you the error.

Try this

Redirections are applied in the order they are written, and that order is the whole behaviour.

2>&1 >out first points errors at wherever output currently goes — the terminal — and only then moves output to the file. >out 2>&1 moves output first, so errors follow it into the file. They look like the same thing and are not.

Try this

This is a recurring defect in generated scripts, and it is pure order of operations.

A redirection on a command lasts for that command. exec applies one to the shell, and it lasts for the rest of the script: exec > run.log at the top means everything after it is captured without repeating >> run.log on every line.

It is also why a script that does it goes quiet. Nothing is broken and nothing failed — the output is in the file, and the terminal will not see another word of it.

Try this

exec cmd is the other half of it: the shell is replaced by the command, so nothing after that line runs. exec "$@" is the last line of most wrapper scripts for exactly that reason.

$

Files

The files in the sandbox, with their modes, link counts and sizes
ModeLinksSizeName
-rw-r--r--1131agenda.md
-rw-r--r--158minutes.txt
-rw-r--r--196receipt.txt