Bash double process substitution gives bad file descriptor

眉间皱痕 提交于 2019-12-22 04:24:44

问题


When I try to refer to two process substitution pipes in a bash function, only the first one referenced works. The second one gives a "bad file descriptor" error like so:

$ foo(){
> cat "$1"
> cat "$2"
> }
$ foo <(echo hi) <(echo bye)
hi
cat: /dev/fd/62: Bad file descriptor
$ 

It appears that the second pipe is dropped once one is referenced, but a) I cannot seem to confirm this behavior in any documentation and b) I wish it wouldn't. =)

Any ideas on what I'm doing wrong? FWIW I'm doing this to make a wrapper to use Mac OS X's FileMerge graphical diff tool instead of the command line one, which is already happy to work with multiple pipes from the command line.

-Rob


回答1:


First, I think @Michael Krelin is right about this being related to the version of bash supplied with OS X (v3.2.48). It looks from my testing as though the file descriptors get discarded after the first external command the function executes:

$ bar() { echo "Args: $*"; echo "First ext command:"; ls /dev/fd; echo "Second ext command:"; ls /dev/fd; }
$ bar <(echo hi) <(echo bye)
Args: /dev/fd/63 /dev/fd/62
First ext command:
0   1   2   3   4   5   6   62  63
Second ext command:
0   1   2   3   4   5   6

Note that /dev/fd/62 and 63 vanish between the two ls listings. I think I found a workaround, though: copy the fragile fd's to non-fragile fd's before they have a chance to vanish:

$ baz() { exec 3<"$1" 4<"$2"; ls /dev/fd; ls /dev/fd; cat /dev/fd/3; cat /dev/fd/4; }
$ baz <(echo hi) <(echo bye)
0   1   2   3   4   5   6   62  63
0   1   2   3   4   5   6
hi
bye



回答2:


The /bin/bash supplied with OSX (3.2.48) fails on that. The one from macports (4.2.37 — normally /opt/local/bin/bash if you have it installed) works fine. Whether it is version or build I don't know. Perhaps you may want to use macports bash for this script. One certainly has to have macports on every mac, so I assume you do ;-)




回答3:


Are you sure you are running it with bash and not some other shell? Have you checked the output of echo $SHELL?

Works fine for me using bash:

[16:03:51][tim@tim(1)]:~
(0)$function foo() { cat "$1"; cat "$2"; };
[16:03:59][tim@tim(1)]:~
(0)$foo <(echo "lva") <(echo hi)
lva
hi

When I change the shebang to #!/bin/dash for example I get errors.

Please try putting #!/bin/bash as a shebang on the first line of your script.




回答4:


This looks like the problem here: http://bugs.alpinelinux.org/issues/1465



来源:https://stackoverflow.com/questions/12674783/bash-double-process-substitution-gives-bad-file-descriptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!