Coder Perfect

Are you unsure what stdin, stdout, and stderr mean?


I’m not sure what these three files are supposed to do. If my understanding is correct, stdin is the file into which a program makes its requests to run a task in the process, stdout is the file into which the kernel publishes its output and the process requesting it reads it, and stderr is the file into which all exceptions are sent. When I opened these files to examine if these things happen, I discovered nothing that seemed to indicate that they do!

What I’d like to know is what the function of these files is, in a completely simplified manner with no technical language!

Asked by Shouvik

Solution #1

Standard input – this is the file handle that your process reads to get information from you.

This file handle is used to write standard output from your process.

This file handle receives diagnostic output from your process, which is a standard error.

That’s about as simple as I can get it:-)

Of course, this is primarily due to tradition. Nothing prevents you from writing your diagnostic data to standard output if you so desire. You can even completely close the three file handles and open your own I/O files.

When your process starts, these handles should already be open, and it may simply read from and/or write to them.

They’re probably attached to your terminal device (e.g., /dev/tty), but shells allow you to connect these handles to certain files and/or devices (or even pipelines to other processes) before your process starts (some of the manipulations possible are rather clever).

An example being:

my_prog <inputfile 2>errorfile | grep XYZ

which will:

Re your comment:

It’s because these aren’t your typical files. Even while UNIX exposes everything as a file in some file system, this isn’t the case at the lowest levels. The majority of files in the /dev hierarchy are character or block devices, which operate as device drivers. They don’t have a size, but they do have a device number that is both major and minor.

You’re connected to the device driver rather than a physical file when you access them, and the device driver is clever enough to know that different operations should be handled separately.

The Linux /proc filesystem is the same way. Those aren’t genuine files; they’re just carefully regulated access points to kernel data.

Answered by paxdiablo

Solution #2

Rather than being files, stdin, stdout, and stderr should be referred to as “I/O streams.” These entities do not exist in the filesystem, as you may have seen. In terms of I/O, however, the Unix concept is “everything is a file.” In reality, this implies that the same library functions and interfaces (printf, scanf, read, write, select, and so on) can be used regardless of whether the I/O stream is connected to a keyboard, a disk file, a socket, a pipe, or any other I/O abstraction.

Most programs need to read input, write output, and log errors, so stdin, stdout, and stderr are predefined for you, as a programming convenience. This is merely a convention that the operating system does not enforce.

Answered by Jim Lewis

Solution #3

As a companion to the previous responses, here is a summary of Redirections:

EDIT: This image isn’t totally accurate.

The first example does not use stdin at all; instead, it uses the echo command to give “hello” as an input.

2>&1 has the same effect as &>, according to the graphic.

ls Documents ABC > dirlist 2>&1
#does not give the same output as 
ls Documents ABC > dirlist &>

This is because &> requires a file to redirect to, and 2>&1 is simply sending stderr into stdout

Answered by Leopold Gault

Solution #4

I’m afraid your comprehension is absolutely incorrect. 🙂

Think of “standard in,” “standard out,” and “standard error” from the perspective of the programme, not the kernel.

When a program has to print output, it usually uses “standard out” as the destination. A program typically prints output to standard out with printf, which prints ONLY to standard out.

When a program needs to publish error information (not exceptions, which are a programming-language feature enforced at a far higher level), it usually prints to “standard error.” It usually does it with fprintf, which takes a file stream as input and prints it. Any file opened for writing could be the file stream: standard out, standard error, or any other file opened with fopen or fdopen.

When the file wants to read input, it uses “standard in” instead of fread, fgets, or getchar.

Any of these files can be routed easily from the shell, as shown here:

cat /etc/passwd > /tmp/out     # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err   # redirect cat's standard error to /tmp/error
cat < /etc/passwd              # redirect cat's standard input to /etc/passwd

Alternatively, you could go for the complete shebang:

cat < /etc/passwd > /tmp/out 2> /tmp/err

There are two key caveats to be aware of: First and foremost, the terms “standard in,” “standard out,” and “standard error” are merely conventions. They’re a powerful convention, but it’s really simply a consensus that it’s great to be able to execute programs like this: sort and have the standard outputs of each program connected into the standard input of the following program in the pipeline | grep echo /etc/services | awk ‘print $2;’

Second, I’ve provided the ISO C functions for working with file streams (FILE * objects) — at the kernel level, it’s all file descriptors (int references to the file table) and much lower-level operations like read and write, which lack the ISO C functions’ pleasant buffering. I figured I’d keep it easy and use the simpler routines, but I figured you should be aware of the options. 🙂

Answered by sarnold

Solution #5

I believe it is misleading to imply that stderr should only be used for error messages.

It should also be used for informative messages intended for the user running the command rather than any potential downstream consumers of the data (for example, if you run a shell pipe chaining several commands, you don’t want informative messages like “getting item 30 of 42424” to appear on stdout because they will confuse the consumer, but you might want the user to see them).

For historical context, consider the following:

Answered by dee

Post is based on