Wednesday, 21 August 2013

strange "bad file descriptor" error

strange "bad file descriptor" error

I've run into a perplexing error that I'd like to understand better. The
problem seems to require the presence of a "wrapper" shell function (as
described below), so my immediate interest is to find out how to modify
such a shell function to get rid of the error. (I give a more specific
statement of my question at the end of the post.)
The simplest code that I've come up with to reproduce this error is given
in the following script. (This script is certainly artificial and silly,
but the real-life situation in which the error first surfaced is a bit too
complicated for a demonstration like this one.)
# create an input file
cat <<EOF > demo.txt
a
b
c
EOF
# create a "wrapper shell function" for /usr/bin/join
my_join_fn () {
/usr/bin/join "$@"
}
cat <(my_join_fn <(cat demo.txt) <(cat demo.txt))
cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
# create a "wrapper shell function" for /usr/local/bin/gjoin, a port of
# GNU's join function for OS X
my_gjoin_fn () {
/usr/local/bin/gjoin "$@"
}
cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt))
cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt)) | head -1
# show the version of zsh
$SHELL --version
If one sources this script (under zsh), it terminates successfully, and
produces the following (correct) output:
% source demo.sh
a
b
c
a
a
b
c
a
zsh 5.0.2 (x86_64-apple-darwin11.4.2)
But if one then re-executes directly from the command line either one of
the two lines in the script that end with | head -1, one gets a bad file
descriptor error:
% cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
join: /dev/fd/11: Bad file descriptor
% cat <(my_gjoin_fn <(cat demo.txt) <(cat demo.txt)) | head -1
/usr/local/bin/gjoin: /dev/fd/11: Bad file descriptor
These are the only two lines in the script that produce an error when run
directly on the command line.
As indicated in the output of $SHELL --version, the results shown above
were obtained under OS X, but I get similar results when I perform an
analogous test under Linux:
% cat <(my_join_fn <(cat demo.txt) <(cat demo.txt)) | head -1
/usr/bin/join: /proc/self/fd/11: No such file or directory
% $SHELL --version
zsh 4.3.10 (x86_64-unknown-linux-gnu)



I have not been able to reproduce this error under bash (OS X or Linux).
This leads me to suspect that the error is due to a bug in zsh. But, if
so, it is an extremely arcane bug, and thus not likely to be fixed any
time soon.
Therefore, I'd like to find a workaround. My question is:
How should I modify the definition of the wrapper shell function
my_gjoin_fn so as to avoid this error?
(The real-life counterpart for my_gjoin_fn is almost identical to the one
given above, differing only in the inclusion of a flag in the invocation
of gjoin:
my_gjoin_fn () {
/usr/local/bin/gjoin -t$'\t' "$@"
}
I use this wrapper shell function all the time, therefore I'd really like
to "salvage" it.)

No comments:

Post a Comment