Unfortunately I've had no luck figuring this out, as everything I find is just on the syntax of redirection, or shallow information about how redirection works.
What I want to know is how bash actually changes stdin
/stdout
/stderr
when you use pipes or redirection. If for example, you execute:
ls -la > diroutput.log
How does it change stdout
of ls
to diroutput.log
?
I assume it works like this:
- Bash runs
fork(2)
to create a copy of itself - Forked bash process sets it's
stdout
todiroutput.log
using something likefreopen(3)
- Forked bash process runs
execve(2)
or a similar exec function to replace itself withls
which now uses thestdout
setup by bash
But that's just my educated guess.
Best Answer
I was able to figure it out using
strace -f
and writing a small proof of concept in C.It appears that bash just manipulates file descriptors in the child process before calling
execve
as I thought.Here's how
ls -la > diroutput.log
works (roughly):fork(2)
diroutput.log
usingopen(2)
.stdout
file descriptor using thedup2(2)
syscallexecve(2)
to replace it's executable image withls
which then inherits the already setupstdout
The relevant syscalls look like this (
strace
output):