ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Here's what I found in C Primer Plus about redirection:
Quote:
The < symbol is a Unix and Linux (and DOS) redirection operator. It causes the words file to be associated with the stdin stream.
So, I understood that < works with streams aka an interface(provided by C) to files.
However, I tried the command:
Code:
./a.out 0 < /etc/motd
and the redirection did took place, but in my example 0 is a file descriptor( the low-level equivalent to C stream).
The question is: why "<" worked with the file descriptor too?
Just to clarify things: in my case, a.out determines the file status flags, using fcntl. It determines the flags well, so I assume the redirection succeded. Am I right?
It looks like this shell command "./a.out 0 < /etc/motd" would make /etc/motd stdin for the running process invoked as "./a.out 0". If you didn't mean to put a space in between the digit and the redirector, ala "./a.out 0< /etc/motd" it would use /etc/motd for file descriptor zero (which is the same as stdin) and run "./a.out".
I understand that, but I don't know why it's happening... stdin is a pointer to a struct (FILE , I guess) and it has nothing to do with file descriptors, no? From what I know, STDIN_FILENO (file descriptor related) != stdin
All programs get three default file descriptors. These have numeric IDs as well as names in C land:
Code:
stdin - read mode, number 0
stdout - write mode, number 1
stderr - write mode, number 2
By default, when you run a program from the shell, the shell connects stdin to the keyboard (for input), stdout and stderr to the terminal's output.
You can ask the shell to over-ride these defaults using re-direction. Changing the destination for stdout and stderr is called output redirection. You do this by using the > symbol and then naming a file to which the output will be written. You explicitly say which file descriptor you want to re-direct by prefixing the > with the number for the file descriptor, e.g. 2> to re-direct stderr. If you don't specify the file descriptor number, 1 (stdout) will be re-directed. For example:
Code:
myprogram > myfile.out
This will put the output which myprogram sends to stdout in the file myfile.out. Note that if myprogram sends output to stderr, this will still be sent to the terminal. In borne style shells (e.g. bash - the default shell on many Linux distros), you can do something like this:
Code:
myprogram > myfile.out 2> myfile.err
...which will send stdout to myfile.out, and stderr to myfile.err.
You can also say something like this:
Code:
myprogram > output 2>&1
The 2>&1 says "put output on file descriptor 2 (stderr) in the same place as file descriptor 1", which in this case is the file "output".
You can also re-direct input, so instead of reading from the keyboard, the program will read from the file. You do it like this:
Code:
myprogram < myfile.in
In this case input is read from the file "myfile.in". By default < puts intput into file descriptor 0. 0< does exactly the same thing, it's just an explicit way of saying it.
You can do them all in one command to different files if you like:
Code:
myprogram < myfile.in > myfile.out 2> myfile.err
Note that if you do this:
Code:
myprogram 1< myfile.in
...it won't work since file descriptor 1 (stdout) has more "write", and so it won't be read from. Same goes for descriptor 2 (stderr).
I understand that, but I don't know why it's happening... stdin is a pointer to a struct (FILE , I guess) and it has nothing to do with file descriptors, no? From what I know, STDIN_FILENO (file descriptor related) != stdin
But unless you reassign the variable stdin, it indicates the FILE struct which describes file descriptor zero. (That is the default environment. And if you change what file belongs to file descriptor zero, stdin will refer to that particular file.) So most of the time, stdin and file descriptor zero are equivalent, referencing the same resource.
From what I know, STDIN_FILENO (file descriptor related) != stdin
For any file that's opened on your system, there is a numerical file descriptor. Standard input is merely the output end of an unnamed fifo, which is a unique file for each redirection pair (unless you are clever), always numbered 0 for the input half and 1 for the output half, corresponding to the STDIN_FILENO and STDOUT_FILENO macros. In order to use standard input, however, you need a stream, which is what 'stdin' is. Because standard input is open when your program starts, 'stdin' is already assigned.
When you redirect, the shell will create two processes: the output process and the input process. It will create an unnamed fifo between them and the processes will run independently. When you do 'myprogram < myfile.in', this is the same as 'cat myfile.in | myprogram' without using the 'cat' program. The '|' can be thought of as a pipe between the first program and the second; the unnamed fifo.
Reassigning 'stdin' doesn't have a lot to do with it. When you reassign, all you do is replace the pipe assigned by the shell with another file so that standard input comes from that file vice shell redirection (if any.)
ta0kira
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.