Yes, using ":" also illustrate the same (or similar) behavior that I'm experiencing with my script. Using the "here" string creates the additional weirdness of showing that the temporary file content is actually "deleted", but the bash process keep the FD open. Which is quite strange since it appears to have done half the job...
Below is another difference with the "here" string construct - of course this is a very inefficient way to assign a string to a variable!!! ;-) but just used as a simple example here. # Start a new shell to make sure there is no old FD left from previous tests bash unset -v TESTVAR 9<<<"test data" read -r -u 9 TESTVAR printf "OUTPUT: $TESTVAR\n" OUTPUT: test data FD #9 is not left open or "deleted" here: lsof -a -d '0-20' -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 12084 mathp 0u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 1u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 2u CHR 136,4 0t0 7 /dev/pts/4 Now testing with the "named" (if that's a good name to call this) FD: unset -v TEST_FD TESTVAR {TEST_FD}<<<"test data" read -r -u $TEST_FD TESTVAR bash: read: TESTVAR: invalid file descriptor specification But strangely, the TEST_FD exists and is left in the "deleted" mode: lsof -a -d '0-20' -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 12084 mathp 0u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 1u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 2u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 10r REG 8,1 10 1049150 /tmp/sh-thd-512950288 (deleted) Looks like the process of dynamically assigning a FD to the FD "variable" breaks the redirection. But the FD is created and it's value did get assigned to TEST_FD: echo $TEST_FD 10 and temporary file content deleted, but the FD not un-linked.... Doing the same thing but using 2 steps works, but you're still left with a "deleted" FD: unset -v TEST_FD TESTVAR : {TEST_FD}<<<"test data" read -r -u $TEST_FD TESTVAR printf "OUTPUT: $TESTVAR FD: $TEST_FD\n" OUTPUT: test data FD: 11 lsof -a -d '0-20' -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 12084 mathp 0u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 1u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 2u CHR 136,4 0t0 7 /dev/pts/4 bash 12084 mathp 10r REG 8,1 10 1049150 /tmp/sh-thd-512950288 (deleted) bash 12084 mathp 11r REG 8,1 10 1049151 /tmp/sh-thd-263257624 (deleted) I think that having a common behavior for "named" vs "numbered" FD in bash would be great since obviously using dynamically assigned FD (numbers) offers some advantages when coding more complex scripts. Also related, assigning the output of the process substitution construct to a "named" FD has the same behavior, i.e. you're left with an un-linked pipe: unset -v TESTVAR 9< <(ls ~/t) read -r -u 9 TESTVAR printf "OUTPUT: $TESTVAR\n" OUTPUT: 0095.out lsof -a -d '0-20' -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 16098 mathp 0u CHR 136,4 0t0 7 /dev/pts/4 bash 16098 mathp 1u CHR 136,4 0t0 7 /dev/pts/4 bash 16098 mathp 2u CHR 136,4 0t0 7 /dev/pts/4 unset -v TEST_FD TESTVAR : {TEST_FD}< <(ls ~/t) read -r -u $TEST_FD TESTVAR printf "OUTPUT: $TESTVAR FD: $TEST_FD\n" OUTPUT: 0095.out FD: 10 lsof -a -d '0-20' -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 16098 mathp 0u CHR 136,4 0t0 7 /dev/pts/4 bash 16098 mathp 1u CHR 136,4 0t0 7 /dev/pts/4 bash 16098 mathp 2u CHR 136,4 0t0 7 /dev/pts/4 bash 16098 mathp 10r FIFO 0,8 0t0 96683179 pipe Thanks! Math. On Thu, Jan 28, 2016 at 8:58 AM, Andreas Schwab <sch...@suse.de> wrote: > Greg Wooledge <wool...@eeg.ccf.org> writes: > > > On Wed, Jan 27, 2016 at 01:18:11PM -0500, Mathieu Patenaude wrote: > >> When using "named" file descriptors inside a function, the file > descriptors > >> are not automatically un-linked when the function returns, but when > using > >> regular "numbered" file descriptors they are automatically "destroyed". > > > > Could not reproduce in an interactive shell, on bash 4.3.30 (Debian). > > > > $ f() { local fd; exec {fd}</dev/null; } > > $ f > > $ g() { exec 9</dev/null; } > > $ g > > $ lsof -p $$ > > ... > > bash 931 wooledg 0u CHR 136,0 0t0 3 /dev/pts/0 > > bash 931 wooledg 1u CHR 136,0 0t0 3 /dev/pts/0 > > bash 931 wooledg 2u CHR 136,0 0t0 3 /dev/pts/0 > > bash 931 wooledg 9r CHR 1,3 0t0 1028 /dev/null > > bash 931 wooledg 10r CHR 1,3 0t0 1028 /dev/null > > bash 931 wooledg 255u CHR 136,0 0t0 3 /dev/pts/0 > > > > I actually ran the lsof multiple times, in between the calls to f and g. > > FD 10 was opened by f (and kept open), and FD 9 was of course opened by g > > (and kept open). > > Try replacing exec with :. Redirections established with exec are > always permanent. > > Andreas. > > -- > Andreas Schwab, SUSE Labs, sch...@suse.de > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 > "And now for something completely different." >