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 ofgrep
.
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 dup
ed 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
How to Send a File as an Email Attachment Using Linux Command Line
How to Remove the Lines Which Appear on File B from Another File A
Exploring Docker Container'S File System
Ld Cannot Find an Existing Library
Split One File into Multiple Files Based on Delimiter
Bluetooth Low Energy: Listening For Notifications/Indications in Linux
Find -Exec' a Shell Function in Linux
How to Start Solr Automatically
Understanding User File Ownership in Docker: How to Avoid Changing Permissions of Linked Volumes
How to Fix 'Sudo: No Tty Present and No Askpass Program Specified' Error
Bash Script Prints "Command Not Found" on Empty Lines
What Does $@ Mean in a Shell Script
Why Does a Jvm Report More Committed Memory Than the Linux Process Resident Set Size
Automating Running Command on Linux from Windows Using Putty