Skip to content
Joachim Ansorg edited this page Nov 12, 2021 · 2 revisions

Multiple redirections compete for stdout. Use cat, tee, or pass filenames instead.

(or stdin, or stderr, or FD 3)

Problematic code:

grep foo < input1 < input2 > output1 > output2 > output3

Correct code:

# Merge inputs into a single stream, write outputs individually
cat input1 input2 | grep foo | tee output1 output2 > output3

# Pass inputs as filenames, write outputs individually
grep foo input1 input2 | tee output1 output2 > output3

Rationale:

A file descriptor, whether stdin, stdout, stderr, or non-standard ones, can only point to a single file/pipe.

For input, many commands support processing multiple filenames. In these cases you can just specify the filenames instead of redirecting. Alternatively, you can use cat to merge multiple filenames into a single stream.

For output, you can use tee to write to multiple output sinks in parallel.

Exceptions:

Zsh will automatically cat inputs and tee outputs, but none of the shells supported by ShellCheck do.

Related resources:

  • Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!

ShellCheck

Each individual ShellCheck warning has its own wiki page like S001. Use GitHub "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally