11

I'm reading a book, it says:

Every process has at least three communication channels available to it: “standard input” (STDIN), “standard output” (STDOUT), and “standard error” (STDERR).

Most commands accept their input from STDIN and write their output to STDOUT. They write error messages to STDERR. This convention lets you string commands together like building blocks to create composite pipelines.

The shell interprets the symbols <, >, and >> as instructions to reroute a command’s input or output to or from a file.

To connect the STDOUT of one command to the STDIN of another, use the | symbol, commonly known as a pipe.

ps -ef | grep httpd

So basically what this is saying is that standard input is a command that allows user to write to a file, while standard output is a command that has the bash shell write output to the shell, and standard error is just like output but it is only invoked when there is an error in file system. Then we get to the part of connecting STDOUT and STDIN and I'm lost.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
JohnMerlino
  • 6,161

2 Answers2

26

Standard input and standard output are not commands.

Imagine commands as machines in a factory with an assembly line. Most machines are designed to have one conveyor belt to feed data in and one conveyor belt to feed data out; they are the standard input and the standard output respectively. The standard error is an opening on the side of the machine where it can eject rejects.

+-------+     +------------------+       +------------------+     +------+
| input |     |    machine A     |       |    machine B     |     |output|
| reser ­­­|=====|<stdin     stdout>|=======|<stdin     stdout>|=====|bucket|
| ‑voir |  →  |      stderr      |   →   |      stderr      |  →  |      |
+-------+     +------------------+       +------------------+     +------+
                      ||                          ||

The diagram above shows a conveyor belt that goes through two machines. The data comes from the input reservoir on the left, is fed to machine A, then the output is conveyed further to machine B (for which it is input), and machine B's output is deposited in the output bucket on the right.

In unix terms, this is called a pipeline. The metaphor is that of plumbing: a pipe connects machine A to machine B. The shell syntax for the pipeline above is

<input-file.txt commandA | commandB >output-file.txt

The < redirection symbol tells the shell to connect commandA's standard input to the file input-file.txt before launching commandA. (You can put the redirection before or after the command name.) The > redirection symbol tells the shell to connect commandB's standard output to output-file.txt. The pipe ("|") symbol in the middle tells the shell to connect commandA's standard output to commandB's standard input before launching them.

Commands can have more than one input and more than one output, but that's material for another day.

  • 4
    The visual helped a lot – JohnMerlino Feb 10 '12 at 01:46
  • Nice analogy. I've understood the concept of the stream pipeline for many years now, but somehow noone has ever used the factory / conveyor analogy, which makes it really easily (and succinctly) understandable. Thank you! – Owen Blacker Feb 28 '12 at 18:34
  • 1
    Great analogy. Going to borrow this one if you don't mind. – Tivie May 30 '12 at 15:31
  • Gilles, I've asked a question on your phrasing at the bottom: http://unix.stackexchange.com/q/96724/29146. could you clarify? – strugee Oct 19 '13 at 06:01
  • @Gilles - Can you include an example that illustrates the option to define the redirection before or after the command? For example, can the pipeline read as input-file.txt > commandA or input-file.txt < commandA? – Motivated Dec 23 '18 at 18:34
  • @Motivated The redirection symbol goes before the input/output file. The redirection as a whole can be before or after the command name. I'm sure this has been covered in full by a question on the site, try searching in https://unix.stackexchange.com/questions/tagged/io-redirection – Gilles 'SO- stop being evil' Dec 24 '18 at 14:11
  • It also helps to remember that <file is a shorthand for 0<file, so 0<file cmd can be read as: 1. connect file to 0/stdin, 2. run cmd. Correspondingly, for >, 1/stdout is inferred left of the > operator if no file descriptor was given there. Hence, cmd >file is a shorthand for cmd 1>file which can be read as: 1. connect 1/stdout to file, 2. run cmd. – Carl Sep 10 '22 at 18:41
6

standard input is a command that allows user to write to a file

Not a command, but a stream. Standard in and out are like mail boxes. When a program starts, it's given a box to recieve and a box to send mail. Usually, input comes from the keyboard and and is put in the in-box, mail put in the out-box ends up on your terminal screen.

standard output is a command that has the bash shell write output to the shell

The program doesn't actually know where standard out points. When you pipe A to B (as in $ A | B), when A puts mail in the out-box, it ends up in B's in-box. B processes the input and puts its own mail in the out-box, which is what you see on the terminal.

To drop the metaphore, as mentioned, standard in/out are streams. The mail box, or file descriptor, is one end of the stream. To pipe is to connect the standard out of A to the standard in of B.