A segmentation fault is a signal, if you are not catching this then your program will be terminated and your shell will print this to its stderr (rather than your program's stderr).
It is possible for either your program or the shell to take specific actions when this occurs, either by the program catching the signal or your shell trapping the SIGCHILD signal and then checking your child's exit status.
It doesn't matter because both 4>&1
and 4<&1
do the same thing: dup2(1, 4)
which is the system call to duplicate a fd onto another. The duplicated fd automatically inherits the I/O direction of the original fd. (same for 4>&-
vs 4<&-
which both resolve to close(4)
, and 4>&1-
which is the dup2(1, 4)
followed by close(1)
).
However, the 4<&1
syntax is confusing unless for some reason the fd 1 was explicitly open for reading (which would be even more confusing), so in my mind should be avoided.
The duplicated fd
shares the same open file description which means they share the same offset in the file (for those file types where it makes sense) and same associated flags (I/O redirection/opening mode, O_APPEND and so on).
On Linux, there's another way to duplicate a fd
(which is not really a duplication) and create a new open file description for the same resource but with possibly different flags.
exec 3> /dev/fd/4
While on Solaris and probably most other Unices, that is more or less equivalent to dup2(4, 3)
, on Linux, that opens the same resource as that pointed to by the fd 4 from scratch.
That is an important difference, because for instance, for a regular file, the offset of fd 3 will be 0 (the beginning of the file) and the file will be truncated (which is why for instance on Linux you need to write tee -a /dev/stderr
instead of tee /dev/stderr
).
And the I/O mode can be different.
Interestingly, if fd 4 pointed to the reading end of a pipe, then fd 3 now points to the writing end (/dev/fd/3
behaves like a named pipe):
$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b
$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b
Best Answer
Where would the error be sent when running
file_2
?When you type
./file_2
(with said file executable), the system actually runs/bin/sh ./file_2
-- i.e. it's running a new copy of/bin/sh
, which is responsible for running the commands in./file2
, and for reporting the errors it finds there, outputting them to stderr.But you've just run that
/bin/sh
with stderr closed. So it wants to emit an error, but has nowhere to do so.Which you can verify with:
The
dup2
fails because fd 2 is closed,sh
tries to report the error on stderr, but that fails as well as stderr (fd 2) is closed.