Leiten Sie stdout bei Erfolg auf command-A um, sonst stderr auf command-b. Vermeiden Sie die Verwendung temporärer Dateien

Leiten Sie stdout bei Erfolg auf command-A um, sonst stderr auf command-b. Vermeiden Sie die Verwendung temporärer Dateien

Ich habe einen Befehl, der bei einwandfreiem Betrieb in stdout schreibt und bei fehlerhaftem Betrieb in stderr. Ich möchte den Beendigungsstatus des Befehls prüfen und entweder mit stdout oder stderr etwas tun.

if ! command >/tmp/stdout 2>/tmp/stderr; then
  // do something with /tmp/stderr
  exit 1
fi

// do something else with /tmp/stdout

Es ist sicherlich möglich, nur eine Datei statt zwei zu haben, aber ich möchte alle Dateien loswerden, nicht nur eine.

Gibt es eine Möglichkeit, die temporären Dateien zu vermeiden? Ich habe es mit mkfifo und benutzerdefinierten Dateideskriptoren versucht, aber das funktioniert nicht.

Antwort1

$(..)Sie können die Befehlsersetzungssyntax in der Bedingung verwenden ifund sehen, ob der Befehl erfolgreich ausgeführt wurde oder nicht und das Ergebnis des Befehls trotzdem sowohl stdoutals auch stderrin einer Variablen speichern

if ! var=$(cmd 2>&1); then
    printf 'process stderr contents from $var'
fi

cmdSie können sehen, wie es funktioniert, wenn ich die Ausführung als einfaches Skript simuliere, das Folgendes tut:

# cat temp.sh    
echo foo >&2
exit 1

und wenn ich das Skript ausführe als

if ! var=$(bash tmp.sh 2>&1); then
    printf '%s\n' 'process stderr contents from $var'
    printf '%s\n' "$var"
fi

Auf die gleiche Weise können Sie es zum Erfassen bringen, stdoutwenn die Befehlsersetzung erfolgreich ist, was im elseobigen Beispiel in der Klausel der Fall sein wird. In beiden Fällen "$var"sorgt die Manipulation des Inhalts (stellen Sie sicher, dass die Anführungszeichen aktiviert sind) dafür, dass Sie das Ergebnis so verarbeiten, als ob es in einer Datei gespeichert wäre.

Sie können weitermachen und die Befehlsersetzungssyntax zitieren, umnichtLassen Sie die Shell die Ergebnisse wortweise trennen. Gehen Sie beispielsweise wie folgt vor. Dies ist möglicherweise nicht für einfache Fälle wie den hier gezeigten erforderlich, sondern für Fälle, in denen die Ergebnisse einige spezielle Shell-Metazeichen enthalten.

if ! var="$(bash tmp.sh 2>&1)"; then

Hinweis: Der Fragentitel wurde umformuliert, seit die erste Version der Antwort gepostet wurde.

Antwort2

Sie können den folgenden Code verwenden

if [[ $? == 0 ]]
then
command 1>stdout.txt
else
echo "exit code is not successfull"
command 2> stderr.txt
fi

verwandte Informationen