Christoph Anton Mitterer wrote, on 11 Mar 2025: > > The original idea was then a construct like: > > ( command exec <some redirections> || exit 125; utility ) > > With 125 assumed as an exit status not used by utility, and the (…) > subshell merely being made to get rid of all those redirections > afterwards. > > With #1879 being clarified, command exec <someRedirections> wouldn't > cause the shell to abort in case of a redirection error. > > The remaining problem was that exec doesn't necessarily pass on > FDs > 2. > > > > Now Harald's intriguing idea was to extend the construct like so: > > ( command exec <some redirections> || exit 125; utility n<&n... m>&m... ) > > With n<&n respectively m>&m being a series of all the FDs from <some > redirections>, intended to make sure they *are* passed on. > > > > My questions back then were: > > a) Does that behaviour even follow from POSIX (in an obvious way where > it's really clear that shells should behave like this, not just > some wobbly way)
The standard doesn't specify what happens for n<&word and n>&word if "n" and "word" have the same numeric value. This is because the description of those redirections say "shall duplicate one input file descriptor from another"; the use of "another" implies they are different file descriptors. I seem to recall this came up on the mailing list years ago, but nothing came of it - probably one reason for that was because nobody could think of a practical use for a same-fd duplication. Now that we do have a practical use, this is worth revisiting. > b) Does it even solve the original problem, or could e.g. such a n<&n > respectively m>&m fail itself (not e.g. because a file doesn't > exist, but because of something like resource exhaustion, etc.) It could potentially solve the original problem if we can get consensus to add something suitable to the standard. It could also make "test -t" portable for file descriptors > 2. E.g.: exec 3> "$outfile" test -t 3 is currently not portable because shells are allowed to close fd 3 when they execute "test". With a suitable update to the standard, it could be made portable by doing: test -t 3 3>&3 > By coincidence, a few days ago Herbert Xu (dash maintainer) posted[0] > that for the sake of dash he considers 0<&0 a no-op, which doesn't > really sound as if the above behaviour would be considered as required > by POSIX, because if it were - and as shells *can* choose not to pass > on FDs > 2 - it couldn't considered to be a no-op?! I think previous discussion identified ksh as the only shell which closes fds > 2; I would expect that in all other shells (or, at least, all the shells whose behaviour we usually pay attention to) n<&n is a no-op as long as fd n is already open. From my testing it looks like it is a no-op in bash, dash, mksh and zsh. So I would support updating the standard to require that n<&n and n>&n are always a no-op if fd n is open, except that if the shell normally closes fds > 2, that were opened with exec, when it executes a non-built-in utility, then applying n<&n or n>&n to such commands causes fd n to remain open. -- Geoff Clare <[email protected]> The Open Group, Apex Plaza, Forbury Road, Reading, RG1 1AX, England
