it-swarm.com.de

echo, das an stderr ausgegeben wird

Gibt es ein Standard-Bash-Tool, das als Echo fungiert, jedoch nicht in stdout, sondern in stderr ausgegeben wird?

Ich weiß, ich kann echo foo 1>&2, aber es ist ziemlich hässlich und, ich vermute, fehleranfällig (z. B. eher fehlerhaft bearbeitet, wenn sich Dinge ändern). 

883
BCS

Diese Frage ist alt, aber Sie könnten dies tun, was das Lesen erleichtert:

>&2 echo "error"

Der Operator >&2 bedeutet wörtlich, die Adresse des Dateideskriptors 1 (stdout) an die Adresse des Dateideskriptors 2 (stderr) für diesen Befehl umzuleiten1. Je nachdem, wie tief Sie es verstehen wollen, lesen Sie dies: http://wiki.bash-hackers.org/howto/redirection_tutorial

Um Interaktionen mit anderen Weiterleitungen zu vermeiden, verwenden Sie eine Subshell

(>&2 echo "error")

1>&2 kopiert den Dateideskriptor # 2 in den Dateideskriptor # 1. Nachdem diese Umleitung durchgeführt wurde, beziehen sich beide Dateideskriptoren daher auf dieselbe Datei: Der einzige Dateideskriptor # 2 war ursprünglich.

1128
Marco Aurelio

Sie können eine Funktion definieren:

echoerr() { echo "[email protected]" 1>&2; }
echoerr hello world

Dies wäre schneller als ein Skript und hat keine Abhängigkeiten.

Der Bash-spezifische Vorschlag von Camilo Martin verwendet einen "Here-String" und gibt alles aus, was Sie daran übergeben, einschließlich Argumenten (-n), die das Echo normalerweise verschlucken würde:

echoerr() { cat <<< "[email protected]" 1>&2; }

Die Lösung von Glenn Jackman vermeidet auch das Problem des Schluckproblems:

echoerr() { printf "%s\n" "$*" >&2; }
377
James Roth

Da 1 die Standardausgabe ist, müssen Sie sie nicht explizit vor einer Ausgabeumleitung wie > benennen, sondern können einfach Folgendes eingeben:

 echo Diese Nachricht geht an stderr> & 2 

Da Sie sich besorgt zu sein scheinen, dass 1>&2 Sie nur schwer zuverlässig tippen kann, könnte die Beseitigung des überflüssigen 1 eine leichte Ermutigung für Sie sein!

212
Brandon Rhodes

Andere Option

echo foo >>/dev/stderr
43
Steven Penny

Nein, das ist die Standardmethode. Es sollte keine Fehler verursachen.

29

Dies ist eine einfache STDERR-Funktion, die die Pipe-Eingabe an STDERR umleitet.

#!/bin/bash
# *************************************************************
# This function redirect the pipe input to STDERR.
#
# @param stream
# @return string
#
function STDERR () {

cat - 1>&2

}

# remove the directory /bubu
if rm /bubu 2>/dev/null; then
    echo "Bubu is gone."
else
    echo "Has anyone seen Bubu?" | STDERR
fi


# run the bubu.sh and redirect you output
[email protected]:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err
12
erselbst

Wenn es Ihnen nichts ausmacht, die Nachricht auch in syslog zu protokollieren, ist not_so_ugly der folgende Weg:

logger -s $msg

Die Option -s bedeutet: "Ausgabe der Nachricht an Standardfehler sowie an das Systemprotokoll."

10

Verwenden Sie nicht cat, da einige hier erwähnt werden. cat ist ein Programm , während echo und printf bash (Shell) sind. Das Starten eines Programms oder eines anderen Skripts (auch oben erwähnt) bedeutet, dass ein neuer Prozess mit all seinen Kosten erstellt wird. Durch die Verwendung von eingebauten Funktionen sind Schreibfunktionen recht billig, da kein Prozess (-Umgebung) erstellt (ausgeführt) werden muss.

Der Benutzer fragt "Gibt es ein Standardwerkzeug zur Ausgabe ( pipe ) an stderr", lautet die kurze Antwort: NEIN ... warum? Das Rediredcting von Pipes ist ein grundlegendes Konzept in Systemen wie Unix (Linux ...) und bash (sh) baut auf diesen Konzepten auf.

Ich stimme mit dem Opener überein, dass das Umleiten mit Notizen wie diesen: &2>1 für moderne Programmierer nicht sehr angenehm ist, aber das ist bash. Bash war nicht dazu gedacht, große und robuste Programme zu schreiben, es soll den Admins dabei helfen, mit weniger Tastendruck dort zu arbeiten ;-)

Und zumindest können Sie die Weiterleitung an beliebiger Stelle in der Zeile platzieren:

$ echo This message >&2 goes to stderr 
This message goes to stderr
9
return42

Hinweis: Ich beantworte die post-nicht die irreführende/vage Frage "Echo, die an stderr ausgibt" (bereits von OP beantwortet).

Verwenden Sie eine Funktion, um die Intentionanzuzeigen und die gewünschte Implementierung zu erhalten. Z.B.

#!/bin/bash

[ -x error_handling ] && . error_handling

filename="foobar.txt"
config_error $filename "invalid value!"

output_xml_error "No such account"

debug_output "Skipping cache"

log_error "Timeout downloading archive"

notify_admin "Out of disk space!"

fatal "failed to open logger!"

Und error_handling sein:

[email protected]

config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }

output_xml_error() { echo "<error>$*</error>" 2>&1; }

debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }

log_error() { logger -s "$*"; }

fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }

notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }

Gründe, die Bedenken in OP behandeln:

  • schönste Syntax möglich (sinnvolle Wörter statt hässlicher Symbole)
  • schwieriger Fehler zu machen (besonders wenn Sie das Skript wiederverwenden)
  • es ist kein Standard-Bash-Tool, aber es kann eine Standard-Shell-Bibliothek für Sie oder Ihr Unternehmen/Ihre Organisation sein

Andere Gründe:

  • klarheit - zeigt die Absicht anderen Betreuern
  • geschwindigkeit - Funktionen sind schneller als Shell - Skripte
  • wiederverwendbarkeit - eine Funktion kann eine andere Funktion aufrufen
  • konfigurierbarkeit - Sie müssen kein Originalskript bearbeiten
  • debugging - einfacher, die für einen Fehler verantwortliche Zeile zu finden (insbesondere, wenn Sie mit einer Tonne Umleitung/Filterung töten)
  • robustheit - Wenn eine Funktion fehlt und Sie das Skript nicht bearbeiten können, können Sie auf ein externes Tool mit demselben Namen zurückgreifen (z. B. kann log_error unter Linux als Alias ​​verwendet werden).
  • implementierungen wechseln - Sie können zu externen Tools wechseln, indem Sie das Attribut "x" der Bibliothek entfernen
  • output-Agnostik - Sie müssen sich nicht mehr darum kümmern, ob sie an STDERR oder anderswo geht
  • personalisierung - Sie können das Verhalten mit Umgebungsvariablen konfigurieren
7
Cezary Baginski

Dies wurde bereits und mit vielen Stimmen beantwortet. Nur für das Protokoll:

echo "my errz" > /proc/self/fd/2

wird effektiv in stderr ausgegeben. Erläuterung: /proc/self ist eine Verknüpfung zum aktuellen Prozess und /proc/self/fd enthält die geöffneten Dateideskriptoren des Prozesses. Dann stehen 0, 1 und 2 für stdin, stdout und stderr.

Ich fand es lesbarer. Auch dies kann in den meisten Linux-Distributionen funktionieren:

echo "my errz" > /dev/stderr

Es macht es deutlich lesbarer.

6
Sebastian

read ist ein in Shell integrierter Befehl, der in stderr druckt und wie ein Echo verwendet werden kann, ohne Umleitungstricks auszuführen:

read -t 0.1 -p "This will be sent to stderr"

Der -t 0.1 ist ein Timeout, bei dem die Hauptfunktionen von read deaktiviert werden, indem eine Zeile stdin in einer Variablen gespeichert wird.

5
Douglas Mayle

Machen Sie ein Skript

#!/bin/sh
echo $* 1>&2

das wäre dein Werkzeug.

Oder machen Sie eine Funktion, wenn Sie kein Skript in einer separaten Datei haben möchten.

2
n0rd

Eine andere Option, auf die ich kürzlich gestoßen bin, ist folgende:

    {
        echo "First error line"
        echo "Second error line"
        echo "Third error line"
    } >&2

Hierbei werden nur integrierte Bash-Funktionen verwendet, während die mehrzeilige Fehlerausgabe weniger fehleranfällig ist (da Sie nicht unbedingt jede Zeile mit &>2 versehen müssen).

0
GuyPaddock