Pipe is used to pass output to another program or utility.
Redirect is used to pass output to either a file or stream.
Example: thing1 > thing2
vs thing1 | thing2
thing1 > thing2
- Your shell will run the program named
thing1
- Everything that
thing1
outputs will be placed in a file called thing2
. (Note - if thing2
exists, it will be overwritten)
If you want to pass the output from program thing1
to a program called thing2
, you could do the following:
thing1 > temp_file && thing2 < temp_file
which would
- run program named
thing1
- save the output into a file named
temp_file
- run program named
thing2
, pretending that the person at the keyboard typed the contents of temp_file
as the input.
However, that's clunky, so they made pipes as a simpler way to do that. thing1 | thing2
does the same thing as thing1 > temp_file && thing2 < temp_file
EDIT to provide more details to question in comment:
If >
tried to be both "pass to program" and "write to file", it could cause problems in both directions.
First example: You are trying to write to a file. There already exists a file with that name that you wish to overwrite. However, the file is executable. Presumably, it would try to execute this file, passing the input. You'd have to do something like write the output to a new filename, then rename the file.
Second example: As Florian Diesch pointed out, what if there's another command elsewhere in the system with the same name (that is in the execute path). If you intended to make a file with that name in your current folder, you'd be stuck.
Thirdly: if you mis-type a command, it wouldn't warn you that the command doesn't exist. Right now, if you type ls | gerp log.txt
it will tell you bash: gerp: command not found
. If >
meant both, it would simply create a new file for you (then warn it doesn't know what to do with log.txt
).
-e
and -f
are options to the ps
command, and pipes take the output of one command and pass it as the input to another. Here is a full breakdown of this command:
ps
- list processes
-e
- show all processes, not just those belonging to the user
-f
- show processes in full format (more detailed than default)
command 1 | command 2
- pass output of command 1 as input to command 2
grep
find lines containing a pattern
processname
- the pattern for grep
to search for in the output of ps -ef
So altogether
ps -ef | grep processname
means: look for lines containing processname
in a detailed overview/snapshot of all current processes, and display those lines
Best Answer
The
&
in2>&1
simply says that the number1
is a file descriptor and not a file name. In this case thestandard output file descriptor
.If you use
2>1
, then this would redirect errors to a file called1
but if you use2>&1
, then it would send it to thestandard output stream
.This
&>
says send both,standard output
andstandard error
, somewhere. For instance,ls <non-existent_file> &> out.file
. Let me illustrate this with an example.Setup:
Create a file
koko
with the following content:Make it executable:
chmod u+x koko
Now note that
j1
doesn't existNow run
./koko &> output
run
cat output
and you will seeBoth,
standard error
(ls: cannot access 'j1': No such file or directory
) andstandard output
(koko2
), were sent to the fileoutput
.Now run it again but this time like so:
Do
cat output
and you will only see thekoko2
like. But not the error output from thels j1
command. That will be sent to thestandard error
which you will see in your terminal.Important note thanks to @Byte Commander:
Note that in
command >file 2>&1
the order of the redirection is important. If you writecommand 2>&1 >file
instead (which is normally not what you want), it will first redirect the command'sstdout
to the file and after that redirect the command'sstderr
to its now unusedstdout
, so it will show up in the terminal and you could pipe it or redirect it again, but it will not be written to the file.