Confused About Stdin, Stdout and Stderr

Confused about stdin, stdout and stderr?

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

Standard output - your process writes conventional output to this file handle.

Standard error - your process writes diagnostic output to this file handle.

That's about as dumbed-down as I can make it :-)

Of course, that's mostly by convention. There's nothing stopping you from writing your diagnostic information to standard output if you wish. You can even close the three file handles totally and open your own files for I/O.

When your process starts, it should already have these handles open and it can just read from and/or write to them.

By default, they're probably connected to your terminal device (e.g., /dev/tty) but shells will allow you to set up connections between these handles and specific 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:

  • create a process for my_prog.
  • open inputfile as your standard input (file handle 0).
  • open errorfile as your standard error (file handle 2).
  • create another process for grep.
  • attach the standard output of my_prog to the standard input of grep.

Re your comment:

When I open these files in /dev folder, how come I never get to see the output of a process running?

It's because they're not normal files. While UNIX presents everything as a file in a file system somewhere, that doesn't make it so at the lowest levels. Most files in the /dev hierarchy are either character or block devices, effectively a device driver. They don't have a size but they do have a major and minor device number.

When you open them, you're connected to the device driver rather than a physical file, and the device driver is smart enough to know that separate processes should be handled separately.

The same is true for the Linux /proc filesystem. Those aren't real files, just tightly controlled gateways to kernel information.

Confused how stdin, stdout and stderr work

the

freopen("myfile.txt" , "a", stdout);

will make your stdout output to the file myfile.txt
This function will redirect the output from console to the file myfile.txt

Even if you use fclose(stdout);, this will not back the output of stdout to the console it will only close the myfile.txt

refer to the following link for more details Strange behaviour when redirecting stdout in C

in order to get the output in both the console and in the file, You have tokeep the stdout untouch do not reopen it with freaopen() and do not close it. and You have to print your message twice in the file and in the stdout

Are stdin and stdout actually the same file?

When the input comes from the console, and the output goes to the console, then all three indeed happen to refer to the same file. (But the console device has quite different implementations for reading and writing.)

Anyway, you should use stdin/stdout/stderr only for their intended purpose; otherwise, redirections like the following would not work:

<inputfile myprogram >outputfile

(Here, stdin and stdout refer to two different files, and stderr refers to the console.)

Why are stdin and stdout seemingly interchangeable?

Because, typically, when a program is invoked from an interactive terminal, with no redirection, both standard input and standard output are connected to the same terminal device, such as /dev/tty (the actual device name varies based on the operating system).

The terminal device is a read/write device. Reading from the terminal device reads terminal input. Writing to the terminal device generates output on the terminal.

You still have discrete file descriptors, 0 and 1, but they're connected to the same device.

Think of it as single, bi-directional pipe, that's duped to both file descriptors 0 and 1.

Linux behaves the same way (you can echo Foo >/dev/stdin and see the output):

$ ls -al /proc/self/fd/[01]
lrwx------. 1 mrsam mrsam 64 Nov 22 21:34 /proc/self/fd/0 -> /dev/pts/1
lrwx------. 1 mrsam mrsam 64 Nov 22 21:34 /proc/self/fd/1 -> /dev/pts/1

So, for this process, file descriptors 0 and 1 is connected to the /dev/pts/1, the same pseudo-terminal device. Whether you are reading from file descriptor 0 or file descriptor 1, you end up reading from the same underlying /dev device, so it makes no difference which actual file descriptor you use.

This is, of course, operating system-dependent. Other POSIX-based operating systems may implement their standard input and output in other ways, where you can't actually write to standard input and read from standard output.

In linux, stdin, stdout, stderr means open file descriptor?

Here is a small C program fd.c that uses stdout and stderr to print a message to the console.

#include <stdio.h>

int main(int argc, char*argv[])
{
fprintf(stdout,"message for stdout\n");
/* fflush(stdout); */
fprintf(stderr,"message for stderr\n");
/* fflush(stderr); */

return 0;
}

To compile: gcc -o fd fd.c

Open a terminal and test run:

./fd
./fd > /tmp/output.log
./fd > /tmp/stdout.log 2>/tmp/stderr.log
./fd > /tmp/all.log 2>&1

Examine each output file. If they look out of sequence, uncomment the fflush statements.

Nothing happens to their relations, they remain as they are as before. The 0,1,2 descriptors are always open by default.



Related Topics



Leave a reply



Submit