Bash process double substitution gives a bad file descriptor

When I try to link to two process substitution channels in a bash function, only the first link works. The second option gives the error "bad file descriptor":

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

It seems that the second channel is discarded as soon as it is referenced, but a) I cannot confirm this behavior in any documentation and b) I would not want this. =)

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

Rob

+6
source share
4 answers

First of all, I think @Michael Krelin is right about the fact that this is due to the bash version shipped with OS X (v3.2.48). From my testing it can be seen that the file descriptors are discarded after the first external command executed by the function:

 $ 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 disappear between the two ls lists. I think I found a workaround: copy the fragile fd to the non-fragile fd before they can disappear:

 $ 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 
+5
source

However, /bin/bash , which ships with OSX (3.2.48), does not work. One of macports (4.2.37 - usually /opt/local/bin/bash if you installed it) works fine. Whether this is a version or an assembly, I don't know. You might want to use macports bash for this script. Of course, there must be macports for each poppy, so I guess you do it; -)

+4
source

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

Works fine for me with 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 shebang to #! / Bin / dash, for example, I get errors.

Try putting #! / Bin / bash as shebang in the first line of your script.

+2
source
0
source

Source: https://habr.com/ru/post/926671/


All Articles