Shell – Difference between > and | with /dev/tty

io-redirectionpipeshell

When I run this command:

echo "1" > /dev/tty # runs successfully 

but when I run this:

echo "1" | /dev/tty #permission denied

What is the difference between these two operators > and | and why does the pipe cause an error?

Best Answer

Short answer: > must be followed by a filename or &n (n is a number), and | must be followed by another command invocation.


Details: In shell syntax, a call to some command contains several components. Example:

A=foo 2>/dev/null B=bar cmd arg1 arg2 >file 3>&4 arg3

Here, parameters 2>/dev/null, >file and 3>&4 are special parameters (containing an unescaped >¹), they are used to establish io-redirections, and can appear anywhere in the command line. Filedesciptor 2 is redirected to /dev/null, filedescriptor 1 (implicit) is redirected to file and filedescriptor 3 is redirected to what filedescriptor 4 was linked to.

Then, among remaining parameters, A=foo and B=bar contain =, so they are not considered as the command name: they give specific values to environment variables of the process to be launched.

Then comes the command cmd and the real arguments: arg1, arg2, arg3.

The pipe | is not part of a command invocation, it links two such invocations together. Example:

CC=gcc make 2>&1 | LESS=--quit-at-eof less

Output on filedescriptor 1 by the first process will be received as input on filedescriptor 0 by the second process, through a “pipe” which acts like a buffer.


1. In fact, the special characters like > are sometimes seen followed by a space. Even though this is allowed, the two (space-separated) strings must be understood as a single ‘entity’.

Related Question