One advantage to allowing the shell to do the open()
like:
utility <in >out
as opposed to allowing the named utility to do the open()
like:
utility in >out
...is that the file-descriptor is secured before the named utility is called, or else if there is an error encountered during the open()
, the utility is never called at all. This is the best way to guard against side-effects of possible race conditions - as can happen from time to time when working with streams and the stream editor.
If a redirection fails, the shell short-circuits the call to the utility and writes an error message to stderr - the shell's stderr and not whatever you might have temporarily directed it to for the utility (well, that depends on the command-line order of redirections as well) - in a standard diagnostic format. The most simple way to test if you can open a file is to open it, and <
does that implicitly before anything else.
Probably the most obvious race condition indicated in the commands in your question involves the out redirection. In both forms the shell does the >
write open as well and this happens regardless of whether sed
can successfully open the readfile in the second form. So out gets truncated - and possibly needlessly. That could be bad if you only wanted to write your output if you could successfully open your input. That's not a problem, though, if you always open your input first, as is done in the first form.
Otherwise, there are at least 10 numerically referenced file descriptors that can be manipulated with shell redirection syntax in that way, and these combinations can get kind of hairy.
Also, when the shell does the open, the descriptor does not belong to the called command - as it does with the second version - but to the shell, and the called command only inherits it. It inherits in the same way any other commands called in the same compound command might be, and so commands can share input that way.