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 why does the pipe cause an error?
> 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
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
1 (implicit) is redirected to
file and filedescriptor
3 is redirected to what filedescriptor 4 was linked to.
Then, among remaining parameters,
=, 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:
| 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’.
| is used to pipe data between processes while
> is used to redirect a stream to a file.
/dev/tty is a "file"/device owned by root and its permissions are set to 666 as a result when you try to pipe to it your shell attempts to execute /dev/tty to stream data to it and it doesn't have execute permissions.