GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum funktioniert die Bash-Prozesssubstitution bei einigen Befehlen nicht?

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.


Linux
  1. Mapping von Metadaten mit Avconv funktioniert nicht?

  2. Warum enthält die Bash-Übersetzungsdatei nicht alle Fehlertexte?

  3. Warum funktioniert die automatische Vervollständigung nicht, wenn ein Befehlsname nach „Quelle“ eingegeben wird?

  4. Linux – Warum funktioniert Locale Es_mx, aber nicht Es?

  5. Rm-Befehl im Bash-Skript funktioniert nicht mit Variablen?

Warum speichert Bash keine Befehle, die mit Leerzeichen beginnen?

Linux – Warum funktioniert Setuid nicht?

Warum stoppt bash bei Fehlern in der Folge von kurzgeschlossenen Befehlen nicht?

Der Musterabgleich funktioniert nicht im Bash-Skript

Warum gibt mir das Wgeting eines Bildes eine Datei und kein Bild?

Warum funktioniert find -mtime bei Dateien mit unterschiedlichen Zeitzonen nicht wie erwartet?