So stoppen Sie die Umleitung in Bash

8

Ich benutze :

exec >script.log 2>&1

in meinem Skript, um alle Ausgaben in eine Datei umzuleiten. Am Ende des Skripts möchte ich eine Nachricht auf dem Bildschirm drucken. Wie stoppe ich die Umleitung?

Willem
quelle

Antworten:

12

Sie können execerneut aufrufen , um die ursprünglichen Deskriptoren wiederherzustellen. Sie müssen sie irgendwo gespeichert haben.

exec 3>&1 4>&2 1>script.log 2>&1
 logged portion 
exec 1>&3 2>&4
echo >&2 "Done"

Innerhalb des protokollierten Teils können Sie die ursprünglichen Deskriptoren für einen Befehl verwenden, indem Sie zu den zusätzlichen Deskriptoren umleiten.

echo "30 seconds remaining" >&3

Alternativ können Sie den protokollierten Teil Ihres Skripts in einen zusammengesetzten Befehl einfügen und diesen zusammengesetzten Befehl umleiten. Dies funktioniert nicht, wenn Sie die ursprünglichen Deskriptoren in einer Falle irgendwo in diesem umgeleiteten Teil verwenden möchten.

{
 logged portion 
} >script.log 2>&1
echo >&2 "Done"
Gilles 'SO - hör auf böse zu sein'
quelle
Die Bemerkung über das Echo >&3macht dies zu meiner bevorzugten Lösung. Danke noch einmal)!
Willem
6

Verwenden Sie additinal fd 3 und 4 für stdout und stderr und leiten Sie einfach 1 und 2 am Ende Ihres Skripts zu ihnen um:

exec 3>&1 4>&2
exec >script.log 2>&1

echo "Some code"

exec >&3 2>&4
echo "Done"
eilen
quelle
Dies gibt einen Fehler zurück:exec 3>/dev/stdout 4>/dev/stderr -bash: /dev/stdout: Permission denied
Willem
Dieser Fehler kann auftreten, wenn Sie versuchen, Ihr Skript in einem anderen Benutzer zu starten. Verwenden Sie Ihr Skript über sudo?
Eile
Ja, das war's: Ich habe ein Su für ein anderes Konto erstellt und den Code ausgeführt. Das Skript, das ich schreibe, wird über sudo ausgeführt, daher werde ich dort auf dasselbe Problem stoßen. Gibt es eine Alternative?
Willem
Ich glaube, es gibt eine elegante Lösung, leider kenne ich die einzige Option, die aus Sicherheitsgründen absolut inakzeptabel sein kann: Fügen Sie Ihren Zielbenutzer zu Ihrer ursprünglichen primären Benutzergruppe hinzu und fügen Sie Gruppenschreibberechtigungen für / proc / self / fd / 1 hinzu vor dem Start des Skripts. (oder noch anfälliger - machen Sie einfach eine temporäre Schreibberechtigung für alle und entfernen Sie sie direkt nach Abschluss des Skripts ohne Gruppenänderungen).
Eile
1
@ Willem Dies kann leicht behoben werden, indem Dateideskriptoren verwendet werden, anstatt die Dateien erneut zu öffnen. Siehe meine Bearbeitung.
Gilles 'SO - hör auf böse zu sein'
1

Zuerst sollten Sie prüfen, ob Sie überhaupt eine Tty haben oder nicht.

if tty -s; then
    echo "Hello, World" > $(tty)
fi
David Baggerman
quelle
1
Beachten Sie, dass auf diese Weise keine Ausgabe an ein externes Programm weitergeleitet werden kann.
Eile
Es ist nicht erforderlich, das externe ttyDienstprogramm zu verwenden. Sie können zum speziellen Gerät umleiten /dev/tty.
Bis auf weiteres angehalten.