Die Meldung "Segmentierungsfehler (Core Dumped)" wird von bash ausgegeben, nicht von dem Programm, das abgestürzt ist (wenn die Meldung ausgegeben wird, ist das Programm bereits tot!). Die Umleitung gilt nur für das Programm selbst.
Um Nachrichten von der Shell selbst über das Programm umzuleiten, führen Sie das Programm in einem Shell-Gruppierungskonstrukt aus und leiten Sie die Ausgabe der gesamten Gruppe um. Das grundlegendste Shell-Gruppierungskonstrukt, das nur eine Gruppe ausführt, sind geschweifte Klammern.
ret=`{ ./segfault; } 2>&1`
Das Formular ret=`eval ./segfault 2>&1`
wendet die Umleitung auf die gesamte Auswertung des eval
Befehls an, daher sollte es im Prinzip funktionieren, und es funktioniert tatsächlich auf meinem Computer mit Bash 4.3.30 und älteren Versionen. Was möglicherweise passiert (und ich kann es mit ksh reproduzieren), ist, dass Ihre Version von bash einige Optimierungen vornimmt, um zu vermeiden, dass Unterprogramme verzweigt werden, wenn sie der letzte Befehl in einer Unterschale sind. Die nominelle Art, den Befehl auszuführen, ret=`eval ./segfault`
ist:
- Erstellen Sie eine Pipe.
- Fork, dh einen Shell-Unterprozess erstellen. Im Unterprozess (Prozess 1):
- Leiten Sie den Ausgang zum Rohr um.
eval
Führen Sie das eingebaute aus.
- Gabel. Im Unterprozess (Prozess 2):
- Führen Sie die Datei aus
./segfault
, dh ersetzen Sie das derzeit in diesem Prozess ausgeführte Shell-Programm durch das segfault
Programm.
- (In Prozess 1) Warten Sie, bis Prozess 2 abgeschlossen ist.
- Prozess 1 wird beendet.
- (Im ursprünglichen Shell-Prozess) Lesen Sie aus der Pipe und akkumulieren Sie die Daten in der
ret
Variablen.
- Wenn das Rohr geschlossen ist, fahren Sie mit der Ausführung fort.
Wie Sie sehen können, erstellt Prozess 1 einen weiteren Prozess, wartet dann auf den Abschluss und wird sofort beendet. Es wäre effizienter, wenn Prozess 1 sich selbst recyceln würde. Einige Shells (und Shell-Versionen) sind besser als andere darin, solche Situationen zu erkennen und eine Tail-Call-Optimierung durchzuführen . Im Fall von ret=`{ ./segfault; } 2>&1`
Prozess 2 wird der Standardfehler jedoch in Dateideskriptor 1 umgeleitet, Prozess 1 jedoch nicht. In der Shell-Version, die Sie ausprobiert haben, hat das Optimierungsprogramm diese Situation nicht erkannt (es hätte einen Endaufruf ausführen können, aber die Umleitung hätte anders eingerichtet werden müssen).