Gelegentlich funktioniert die Prozesssubstitution nicht wie erwartet. Hier ist ein Beispiel:
Eingabe:
gcc <(echo 'int main(){return 0;}')
Ausgabe:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Eingabe:
Aber es funktioniert wie erwartet, wenn es mit einem anderen Befehl verwendet wird:
grep main <(echo 'int main(){return 0;}')
Ausgabe:
int main(){return 0;}
Ich habe ähnliche Fehler bei anderen Befehlen festgestellt (d. h. der Befehl, der die Datei von der Prozessersetzung erwartet, kann /dev/fd/63
nicht verwenden oder ähnliches). Dieser Fehler mit gcc
ist nur das neuste. Gibt es eine allgemeine Regel, die ich beachten sollte, um zu bestimmen, wann die Prozesssubstitution auf diese Weise fehlschlägt und nicht verwendet werden sollte?
Ich verwende diese BASH-Version auf Ubuntu 12.04 (ich habe dies auch in Arch und Debian gesehen):
GNU Bash, Version 4.3.11(1)-Release (i686-pc-linux-gnu)
Akzeptierte Antwort:
Die Prozesssubstitution führt zu einer speziellen Datei (wie /dev/fd/63
in Ihrem Beispiel), das sich wie das Leseende einer benannten Pipe verhält. Diese Datei kann geöffnet und gelesen, aber nicht geschrieben, nicht gesucht werden.
Befehle, die ihre Argumente als reine Streams behandeln, funktionieren, während Befehle, die erwarten, dass sie in Dateien suchen (oder in sie schreiben), nicht funktionieren. Die Art von Befehl, die funktioniert, wird normalerweise als Filter bezeichnet:cat
, grep
, sed
, gzip
, awk
, etc… Ein Beispiel für einen Befehl, der nicht funktioniert, ist ein Editor wie vi
oder eine Dateioperation wie mv
.
gcc
möchte in der Lage sein, wahlfreien Zugriff auf seine Eingabedateien durchzuführen, um zu erkennen, in welcher Sprache sie geschrieben sind. Wenn Sie stattdessen gcc
angeben einen Hinweis auf die Sprache der Eingabedatei, kann die Datei gerne gestreamt werden:
gcc -x c <(echo 'int main(){return 0;}')
Die einfachere, unkompliziertere Form ohne Prozessersetzung funktioniert auch:
echo 'int main(){return 0;}' | gcc -x c -
Beachten Sie, dass dies nicht spezifisch für bash
ist . Alle Shells, die Prozesssubstitution unterstützen, verhalten sich gleich.