2022 Stimmen

Wie man mit der Bash sowohl die Standardausgabe als auch den Standardfehler in eine Datei umleitet und anhängt

Umleiten Standardausgabe zu einer abgeschnittenen Datei in Bash, weiß ich zu verwenden:

cmd > file.txt

Um die Standardausgabe in der Bash umzuleiten und an eine Datei anzuhängen, weiß ich, wie man das macht:

cmd >> file.txt

Um sowohl die Standardausgabe als auch die Standardfehler zu einer abgeschnittenen Datei, weiß ich zu verwenden:

cmd &> file.txt

Wie kann ich sowohl die Standardausgabe als auch die Standardfehlerausgabe in eine Datei umleiten? cmd &>> file.txt hat bei mir nicht funktioniert.

36voto

Quintus.Zhou Punkte 903

Versuchen Sie dies:

You_command 1> output.log  2>&1

Ihre Verwendung von &> x.file funktioniert auch in Bash 4. Entschuldigung dafür: (

Hier kommen einige zusätzliche Tipps.

0, 1, 2, ..., 9 sind Dateideskriptoren in der Bash.

0 steht für Standardeingabe , 1 steht für Standardausgabe , 2 steht für Standardfehler . 3~9 ist für jede andere vorübergehende Verwendung frei.

Jeder Dateideskriptor kann auf einen anderen Dateideskriptor oder eine Datei umgeleitet werden, indem der Operator > o >> (anhängen).

Verwendung: < datei_deskriptor > > < Dateiname | &file_descriptor >

Bitte beachten Sie den Hinweis in Kapitel 20. E/A-Umleitung .

21voto

F. Hauri Punkte 57640

Umleitungen vom Skript selbst

Sie könnten Umleitungen aus dem Skript selbst planen:

#!/bin/bash

exec 1>>logfile.txt
exec 2>&1

/bin/ls -ld /tmp /tnt

Durch die Ausführung wird Folgendes erstellt/angefügt logfile.txt , enthaltend:

/bin/ls: cannot access '/tnt': No such file or directory
drwxrwxrwt 2 root root 4096 Apr  5 11:20 /tmp

Protokollierung in vielen verschiedenen Dateien

Sie könnten zwei verschiedene Protokolldateien erstellen und an eine anhängen Insgesamt Log und die Neuerstellung eines anderen zuletzt Protokoll:

#!/bin/bash

if [ -e last.log ] ;then
    mv -f last.log last.old
fi
exec 1> >(tee -a overall.log /dev/tty >last.log)
exec 2>&1

ls -ld /tnt /tmp

Die Ausführung dieses Skripts bewirkt

  • wenn last.log bereits existieren, benennen Sie sie um in last.old (Überschreiben last.old wenn sie existieren).
  • eine neue last.log .
  • alles anhängen an overall.log
  • alles auf dem Terminal ausgeben.

Einfach y kombinierte Protokolle

#!/bin/bash

[ -e last.err ] && mv -f last.err lasterr.old
[ -e last.log ] && mv -f last.log lastlog.old

exec 2> >(tee -a overall.err combined.log /dev/tty >last.err)
exec 1> >(tee -a overall.log combined.log /dev/tty >last.log)

ls -ld /tnt /tmp

Sie haben also

  • last.log Protokolldatei des letzten Laufs
  • last.err Fehlerdatei des letzten Laufs
  • lastlog.old Protokolldatei des vorherigen Laufs
  • lasterr.old Fehlerdatei des vorherigen Laufs
  • overall.log angehängte Gesamtprotokolldatei
  • overall.err angehängte Gesamtfehlerdatei
  • combined.log angehängte kombinierte Gesamtfehler- und Protokolldatei.
  • noch auf dem Terminal ausgeben

Und für interaktive Sitzungen verwenden Sie stdbuf :

Wenn Sie dies in folgenden Bereichen verwenden möchten interaktiv Schale, müssen Sie sagen tee seine Ein- und Ausgänge nicht zu puffern:

# Source this to multi-log your session
[ -e last.err ] && mv -f last.err lasterr.old
[ -e last.log ] && mv -f last.log lastlog.old
exec 2> >(exec stdbuf -i0 -o0 tee -a overall.err combined.log /dev/tty >last.err)
exec 1> >(exec stdbuf -i0 -o0 tee -a overall.log combined.log /dev/tty >last.log)

Sobald bezogen könnten Sie dies versuchen:

ls -ld /tnt /tmp

19voto

jamesdlin Punkte 63159

Ein anderer Ansatz:

Wenn Sie ältere Versionen der Bash verwenden, bei denen &>> nicht verfügbar ist, können Sie auch tun:

(cmd 2>&1) >> file.txt

Dies erzeugt eine Subshell und ist daher weniger effizient als der traditionelle Ansatz von cmd >> file.txt 2>&1 und funktioniert folglich nicht für Befehle, die die aktuelle Shell verändern müssen (z.B. cd , pushd ), aber dieser Ansatz scheint mir natürlicher und verständlicher zu sein:

  1. Standardfehler auf die Standardausgabe umleiten.
  2. Leiten Sie die neue Standardausgabe durch Anhängen an eine Datei um.

Außerdem wird durch die Klammern jede Unklarheit über die Reihenfolge beseitigt, insbesondere wenn Sie die Standardausgabe und den Standardfehler an einen anderen Befehl weiterleiten möchten.

Um den Start einer Subshell zu vermeiden, können Sie stattdessen geschweifte Klammern verwenden, um eine Gruppenbefehl :

{ cmd 2>&1; } >> file.txt

(Beachten Sie, dass ein Semikolon (oder ein Zeilenumbruch) erforderlich ist, um den Gruppenbefehl zu beenden).

0voto

Ana Nimbus Punkte 547

Wenn Sie sich für die Reihenfolge der Inhalte der beiden Streams interessieren, lesen Sie die Antwort von @ed-morton auf eine ähnliche Frage, aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X