Warum gibt ein Bash-Skript immer noch an stdout aus, selbst wenn ich es an stderr umleite?

Warum gibt ein Bash-Skript immer noch an stdout aus, selbst wenn ich es an stderr umleite?

Ich habe ein Bash-Skript:

#!/bin/bash
echo this should be visible only in the stderr output but it is not 1>&2
exit 0

Außerdem habe ich eine benutzerdefinierte App, die dieses Skript startet. Die App erfasst sowohl stdout als auch stderr. Der stdout ist leer und der stderr enthält den bereitgestellten Text. So weit, so gut. Aber wenn ich das Skript von der Konsole (physisches Terminal) aus starte:

./my_script.sh

Ich erwarte, dass nichts auf dem Display gedruckt wird, aber es wird gedruckt. Ich habe verschiedene Umleitungskombinationen ausprobiert, z. B. >&2, >/dev/stderr, usw., aber das Ergebnis ist das gleiche. Ich habe auch versucht, stdout auf null umzuleiten 1>&2 >/dev/null, aber offensichtlich wird mein Text auch an null gesendet.

Wo ist das konfiguriert? Wie kann ich mein Terminal so einstellen, dass es stderr nicht anzeigt?

Antwort1

Um zu verhindern, dass das Skript seinen Standardfehlerstrom an das Terminal sendet, müssen Sie ihn an /dev/nulloder in eine Datei umleiten.

Dies erreichen Sie, indem Sie das Skript mit der Umleitung des Standardfehlerstroms in der Befehlszeile aufrufen oder das Skript seinen Fehlerstrom selbst umleiten lassen.

Um den Fehlerstrom /dev/nullauf die Kommandozeile umzuleiten, rufen Sie das Skript mit

./my_script 2>/dev/null

Wenn Sie möchten, dass das Skript seinen Standardfehlerdatenstrom automatisch verwirft, leiten Sie den Datenstrom /dev/nullinnerhalb des Skripts um:

#!/bin/bash

# Discard any diagnostic output, errors, and interactive prompts.
exec 2>/dev/null

echo 'This should not be visible.' >&2
echo 'This should be visible.'

Ändern Sie /dev/nullden Pfadnamen einer Datei, um die Diagnoseausgabe stattdessen an diese Datei zu übergeben.

Der Standardausgabestrom wird durch die Umleitung des Standardfehlerstroms zu /dev/nulloder in eine Datei nicht beeinflusst.

Beachten Sie, dass ein Skript normalerweise nicht durch beendet werden sollte exit 0.

Antwort2

So veranlassen Sie, dass dieses spezielle Skript seine Standardausgabe verwirft:

Gegeben sei ein Skript:

date
date -r /var/empty/foo

bearbeiten Sie es zu einemGruppenbefehl. Durch diese Gruppierung der Befehle können die Standardausgabe- und Standardfehlerströme der kombinierten Befehle so behandelt (umgeleitet, weitergeleitet, verworfen usw.) werden, als wäre die Gruppe logisch ein einzelner Befehl.

Zum Beispiel:

{
date
date -r /var/empty/foo
} > /dev/null

verwirft die Standardausgabe, ändert aber nicht die Weiterleitung des Standardfehlerstroms.

Das folgende Skript:

{
date
date -r /var/empty/foo
} > /dev/null 2>&1

leitet seine Standardausgabe nach /dev/null um und leitet dann seinen Standardfehler an seine Standardausgabe um, wodurch sowohl stderr als auch stdout verworfen werden. Diese spezielle Syntax ist äquivalent zu:

{
date
date -r /var/empty/foo
} > /dev/null 2>/dev/null

verwandte Informationen