In the current devel branch, even if we close all standard streams of a background process started in `eval' in a command substitution, the command substitution blocks until the background process terminates.
The following is a reduced test case: $ ./bash -c 'pid=$(eval "sleep 3" < /dev/null &> /dev/null & echo "$!")' In all the older Bash versions, the above command exits immediately after receiving the contents of $!. However, in Bash on the devel branch, the above command waits for the termination of the background process. The issue doesn't happen without "eval". The behavior change was introduced in commit 044c1ac with the following change log: > 2/15 > ---- > execute_cmd.c > - execute_subshell_builtin_or_function: after executing the command(s) > and before running the EXIT trap, undo any redirections from the > last command so the exit trap runs in an environment without those > redirections. This makes builtins run in a subshell more like those > run in the shell's execution environment Bash started to preserve the original stdout (connected to the pipe of the command substitution) for the undo redirections for a possible execution of the EXIT trap, even if the user tries to close the file descriptor of the background process by redirecting it to /dev/null. The present behavior isn't consistent with older Bash versions. Also, the above use of command substitution is typical. Although the specific use of `eval' in this pattern may not be typical, I hit this through a utility that receives an arbitrary string as a command and starts it as a background process. Couldn't the behavior be adjusted? For example, when the EXIT trap is not set (or is inactive in the current subshell), we do not have to preserve the original file descriptors for those undo redirections. -- Koichi
