2016-08-08 11 views
1

Wenn ProgramA von einem externen Prozess (killed: 9) getötet wird, kann ich nicht seine Ausgabe (Std/Stderr) umleiten oder speichern Sie es in eine Variable.Bash speichern/redirect stdout und stderr wenn Programm getötet wird

Programa:

$ ./ProgramA arg1 
    This is on stderr 
    This is on stdout 
    Killed: 9 

Failing einer Variablen zu speichern:

$ ProgramA_Output=`ProgramA arg1` 
$ echo "$ProgramA_Output" 

$ 

Umleitung in eine Datei auch nicht arbeiten:

$ ProgramA arg1 > output.txt 
$ cat ./output.txt 
$ 

Irgendwelche Hinweise zu speichern/Umleitung der Ausgabe?

+1

Wenn es die Shell selbst ist, die getötet wird, können Sie ** nichts ** auf einem SIGKILL tun. Das ist der springende Punkt der Verwendung von SIGTERM anstelle von SIGTERM (und umgekehrt der Punkt, wo SIGTERM verwendet wird, wann immer es möglich ist): Es kann nicht gefangen/gehandhabt werden und wird daher garantiert sofort abgeschlossen [ohne blockierende Syscalls oder ähnliches] , aber * auch * garantiert, das Programm, das getötet wird, nicht zu säubern, flush seine Ausgangspuffer, etc. –

+1

Das sagte, hast du 'ProgramA' geschrieben? Wenn dies der Fall ist, können Sie die Puffer früher spülen. –

+0

Leider habe ich 'ProgramA' nicht geschrieben und bin mir nicht sicher, was es überhaupt verursacht hat. –

Antwort

2

Die wahrscheinlichste unmittelbare Ursache hier ist, dass Ihr Programm seine Puffer nur Zeile für Zeile löscht, wenn es an ein TTY ausgegeben wird; wenn es zu einer Datei oder einem FIFO umgeleitet wird, ist es daher bei der Auslieferung von SIGKILL noch nicht geleert - und da ein SIGKILL nicht gefangen oder verzögert werden kann, hat es zu diesem Zeitpunkt keine Möglichkeit, einen Flush auszuführen.

Wenn Sie auf einer GNU-Plattform sind, können Sie stdbuf verwenden dieses Verhalten standardmäßig zu ändern:

stdbuf -o0 ./ProgramA arg1 >output.txt 

... oder ...

output=$(stdbuf -o0 ./ProgramA arg1) 

Da Sie, dass es wissen Wenn die Ausgabe auf einem TTY-Wert liegt (da die Ausgabe sofort angezeigt wird, wenn sie ohne Umleitung ausgeführt wird), können Sie auch unbuffer (ein Werkzeug, das mit expect ausgeliefert wird) verwenden, um diesen Effekt zu simulieren:

output=$(unbuffer ./ProgramA arg1) 

jedoch das sicherste, was zu tun, um die Quelle von ProgramA zu modifizieren explizit eine Flush-Operation auszuführen, nachdem jeder schreiben Sie sicherstellen wollen, ist komplett - und nur SIGKILL zu verwenden, wenn es unbedingt erforderlich. (Eine übliche Praxis ist es, ein SIGTERM zu verwenden, auf einen längeren Zeitraum zu warten und erst dann auf ein SIGKILL zurückzugreifen).

Verwandte Themen