Why do shells implement alternative means like <<<, < <(command) and < /dev/fd/* to redirect something to stdin when pipes do exist?


The | way (classic pipes)

echo 'text' | sed 's/x/y/'
# or
cat - | sed 's/x/y/' # type text afterwards

The <<< way

sed 's/x/y/' <<< 'text'

The < <(command) way

sed 's/x/y/' < <(echo 'text')
# while <(command) becomes a file descriptor like
sed 's/x/y/' < /dev/fd/42

All of them return teyt.

  • So you're saying we should be doing tr ... < <(cat some-file) or cat some-file | tr ... instead of just tr ... < some-file? Why?
    – muru
    Mar 15 at 3:57
  • Convenience and nuances (example). Mar 15 at 6:13
  • It seems that mentioning process substitutions here is out of place as they are not in themselves redirections. The redirection you show is an ordinary one, with <, redirecting the process substitution, which is a pathname. This makes it no more "special" than redirecting from some file, just like with redirecting from stuff beneath /dev/fd.
    – Kusalananda
    Mar 15 at 6:38

2 Answers 2


Because a pipe must be fed by a process. The < redirection doesn't need a process, it can be fed by a file. The < redirection was also created long before the <<< and <( ...) operations were invented.

And it's also a complement (counterpart) to the > output redirection. Having basic functions that are complementary to each other is a good thing.

  • In addition to being more efficient than cat somefile |..., input redirection from a file with < is also more flexible. For example, you can't use seek() on a pipe (to skip forward or backward in it), but you can on a file read via <. So e.g. cat hugefile | tail can take much longer than tail <hugefile because that can start at the end and work backward. Mar 15 at 7:25

Sotto goes into largely aesthetic reasons, but there are also technical ones. For example, pipes typically result in a subprocess for the right hand side, which means that you cannot set states or variables that you expect to be available later there. Compare:

$ echo foo > 1
$ line=bar; cat 1 | read -r line; echo "$line"
$ line=bar; read -r line < 1; echo "$line"

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.