On Sun, Jun 26, 2011 at 4:06 PM, Dave Reisner <[email protected]> wrote: > On Sun, Jun 26, 2011 at 03:12:24PM +0200, Kurt J. Bosch wrote: >> Tom Gundersen, 2011-06-26 13:51: >> >On Sun, Jun 26, 2011 at 1:03 PM, Kurt J. Bosch >> ><[email protected]> wrote: >> >>The following test case (run in a terminal) >> >> >> >>#!/bin/bash >> >> >> >># custom override example >> >>stat_busy() { >> >> if (( PUSH_MSG )); then >> >> # This triggers the error in "$@" below >> >> # actual code was: >> >> # echo set message "$1"> "$spl_fifo"& >> >> :& >> >> fi >> >> echo "$1" BUSY >> >>} >> >> >> >>status() { >> >> stat_busy "$1" >> >> shift >> >> "$@" >> >> local retval=$? >> >> (( retval == 0 ))&& echo DONE || echo FAIL "($retval)" >> >>} >> >> >> >>PUSH_MSG=0 status "test #0" cat<(echo foo) >> >>PUSH_MSG=1 status "test #1" cat<(echo foo) >> > >> >[...] >> > >> >>CCing Tom Gundersen. >> > >> >Thanks. >> > >> >I have not figured it out, but here is a more minimal test: >> > >> > >> >#!/bin/bash >> > >> > >> >test_one() { >> > : & >> > "$@" >> >} >> > >> >test_two() { >> > : >> > "$@" >> >} >> > >> ># working >> >test_one eval 'cat<(echo foo)' >> >test_two cat<(echo foo) >> > >> >#not working >> >test_one cat<(echo foo) >> >> Confirmed. >> >> -- >> Kurt > > Now I see it (at least in Tom's example). It's expected behavior. You're > only allowed to read the file descriptor created by a PE once. However, > because file descriptors are inherited by subshells, when the subshell > ends, the file descriptor is closed and it goes away. Look at what > happens when you modify the script slightly: > > ------------------- > > #!/bin/bash > > test_one() { > ls /dev/fd/ > : & > ls /dev/fd/ > "$@" > } > > test_one cat <(echo foo) > > ------------------- > > And then run it with debug output.... > > +foo[11]: test_one cat /dev/fd/63 > +foo[4]: ls /dev/fd/ > ++foo[11]: echo foo > 0 1 2 3 63 > +foo[6]: ls /dev/fd/ > +foo[5]: : > 0 1 2 3 > +foo[7]: cat /dev/fd/63 > cat: /dev/fd/63: No such file or directory > > The subshell inherits the descriptor and closes it on exit, destroying > it for the parent. The eval "works" because the FD for the process > substitution isn't created until _after_ the subshell. > > Can we _not_ do this? Our old solution didn't require voodoo like this, > and it worked just fine (albeit a few more SLOC). Not everything needs > to be a one line operation. Perhaps we could just write a simple > function to take care of all these 1 line files that we write to: > > write_oneline_file() { > local file=$1 line=$2 mode=$3 > > printf '%s\n' "$line" >"$file" > [[ $mode ]] && chmod "$mode" "$file" > } > > Which satisfies both parties, as it appears to be a one liner in > execution, but it's actually sane on the back end.
Thanks for your explanation Dave. I like your solution, should make things more readable. -t [sorry for duplicate, forgot CC]
