2012-10-01 5 views
6

Wenn ich versuche, auf zwei Prozeßersetzungs-Pipes in einer Bash-Funktion verweisen, funktioniert nur die erste referenziert. Die zweite gibt eine „schlechte Dateideskriptor“ Fehler wie so:Bash doppelte Prozesssubstitution gibt einen schlechten Dateideskriptor

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

Es scheint, dass das zweite Rohr fallen gelassen wird, sobald man verwiesen, aber a) Ich kann dieses Verhalten nicht in irgendeiner Dokumentation zu bestätigen scheinen, und b) Ich wünschte, es würde nicht. =)

Irgendwelche Ideen zu was ich falsch mache? FWIW Ich mache das, um einen Wrapper für die Verwendung des grafischen Diff-Tools von FileMerge von Mac OS X anstelle der Befehlszeile 1 zu erstellen, die bereits mit mehreren Pipes von der Befehlszeile aus arbeiten kann.

-ROB

Antwort

2

Sind Sie sicher, dass Sie es mit bash und nicht eine andere Shell ausgeführt werden? Haben Sie die Ausgabe von echo $SHELL überprüft?

funktioniert gut für mich bash mit:

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

Wenn ich die shebang zu ändern #/bin/dash zum Beispiel bekomme ich Fehler.

Bitte versuchen Sie, #!/Bin/bash als Shebang in die erste Zeile Ihres Skripts zu setzen.

+0

Das ist keine Antwort ... Ich habe gerade überprüft - es funktioniert auf Linux und schlägt auf OSX, die die OP-Plattform zu sein scheint. –

4

Die mit OSX (3.2.48) gelieferte /bin/bash schlägt fehl. Die von Macports (4.2.37 - normalerweise /opt/local/bin/bash, wenn Sie es installiert haben) funktioniert gut. Ob es Version oder Build ist, weiß ich nicht. Vielleicht möchten Sie Maccasts Bash für dieses Skript verwenden. Man muss Macports auf jedem Mac haben, also nehme ich an, dass du es tust ;-)

+0

Ja, Macports Bash hat es für mich repariert. Ich aktualisiere meinen Terminal-Login. Vielen Dank! – rharder

5

Zuerst denke ich @ Michael Krelin hat recht damit, dass es mit der Version von bash aus OS X (v3.2.48) verwandt ist. Es sieht aus meinen Tests, als ob die Datei-Deskriptoren nach dem ersten externen Befehl verworfen erhalten die Funktion ausführt:

$ 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 

zu beachten, dass/dev/fd/62 und 63 verschwinden zwischen den beiden ls Angeboten. Ich glaube, ich eine Abhilfe gefunden, aber: die fragilen fd die auf nicht-zerbrechlich fd die kopieren, bevor sie eine Chance hat, zu verschwinden:

$ 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 
+0

großartige Workaround. Ja, tut mir leid, nicht angegeben zu haben, aber das seltsame Verhalten war auf OS X 10.8. Ich bemerke, dass dieses seltsame Verhalten auch nicht in Cygwin aufgetreten ist. Ich werde wahrscheinlich zur Macports-Bash wechseln, wenn das "richtig" funktioniert. – rharder

+0

+1 für die Problemumgehung. Total unpraktisch, aber cool ;-) –