Could anyone kindly clarify the following comment:
"Close fd 3 for 'grep' (but not 'ls')":
exec 3>&1 # Save current "value" of stdout.
ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not
'ls').
# ^^^^ ^^^^
exec 3>&- # Now close it for the remainder
of the script.
Why not for 'ls'?
Regards
Dimitre
The "3>&-" just to the left of the comment does close fd 3 for grep but
not ls. There is a second 3>&- just to the left of the pipe that closes
it for the shell that will turn into ls.
Short answer, as it is a different process.
The first thing that the shell notices in the second line is there is a
pipe. To handle this it calls fork() to create another process, and then
each side of the pipe is handled in a different shell. Each shell then
handles the redirection ("2>&1 >&3 3>&-" for one shell and "3>&-" for the
other shell), and then each shell runs the command.
(There are lots of things I have skipped over, for example is it the
parent or the child that becomes the left hand side of the pipeline, how
running the command might differ depending on if the command is a builtin
to the shell or not, if even the redirection is handled differently or
not if it is a builtin command)
Icarus,
thank you for clarifying!
It was my wrong interpretation that fd 3 of the ls parent shell remains
open at that point (that the second 3>&- just to the left of the pipe
doesn't close fd 3 for ls).
Best regards
Dimitre