I have a question. Maybe it's not technically a bug as fd > 9 is involved, but the resulting behavior appears to be strange. I received some reports from users in my project and tried to find out what is happening. This is a reduced case:
#!/usr/bin/env bash enable -f /path/to/lib/bash/fdflags fdflags exec 50>1.txt fdflags -s +cloexec 50 exec 50>2.txt echo hello >&50 ls -l 1.txt 2.txt The result is $ ./reduced.sh -rw-r--r-- 1 murase murase 6 2024-02-24 13:53:01 1.txt -rw-r--r-- 1 murase murase 0 2024-02-24 13:53:01 2.txt I expect that the string `hello' is saved in 2.txt, but it actually goes into 1.txt. It turned out that the redirection "50>2.txt" is actually performed, but it's immediately undone at the end of `exec' command. The undo redirection is set up in the if statement starting on redir.c:1288 (devel 43ecbeb3). The code comment says: /* experimental: if we're saving a redirection to undo for a file descriptor above SHELL_FD_BASE, add a redirection to be undone if the exec builtin causes redirections to be discarded. There needs to be a difference between fds that are used to save other fds and then are the target of user redirections and fds that are just the target of user redirections. We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE that have the close-on-exec flag set are assumed to be fds used internally to save others. */ This piece of the code seems to be introduced in commit cac4cdbf (ChangeLog says the change to redir.c was made on 2011-10-09): https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=cac4cdbf5 I'm just curious about the background of this different treatment for "fds that are used to save other fds and then are the target of user redirections" (quoted from the code comment). Also, it says "experimental", but is there any alternative implementation, where the user-supplied O_CLOEXEC fds are not undone? Even if there is a technical background, the current behavior observed by the users is strange, and this behavior doesn't seem to be specified in the Bash documentation. The documentation just says Redirections using file descriptors greater than 9 should be used with care, as they may conflict with file descriptors the shell uses internally. but this behavior is non-trivial even if the user treats the fds with "care". Note that, in the actual code, the number 50 in the above reduced case is chosen to be a number that is not used (which can be tested by e.g. « ! : >&50 ». There can be false-negatives with this test, but that's fine). -- Koichi