2010-03-25 5 views
10

Ich habe ein Skript. Ich möchte diesem Skript einen ruhigen Modus und einen ausführlichen Modus geben. Wie kann ich die Ausgabe eines Befehls bedingt an/dev/null umleiten?

Dies ist das Äquivalent von:

if $verbose 
then 
    redirect="> /dev/null" 
fi 

echo "Verbose mode enabled" $redirect # This doesn't work because the redirect isn't evaluated. 

Ich würde wirklich wie ein besserer Weg, dies zu tun, als das Schreiben, wenn-elses für jede Anweisung betroffen.

Eval könnte funktionieren, hat aber offensichtliche Nebenwirkungen auf andere Variablen.

Antwort

10

Sie könnten eine Wrapper-Funktion schreiben:

redirect_cmd() { 
    # write your test however you want; this just tests if SILENT is non-empty 
    if [ -n "$SILENT" ]; then 
     "[email protected]" > /dev/null 
    else 
     "[email protected]" 
    fi 
} 

Sie können dann verwenden, jeden Befehl mit der Umleitung auszuführen:

redirect_cmd echo "unsilenced echo" 
redirect_cmd ls -d foo* 

SILENCE=1 
redirect_cmd echo "nothing will be printed" 
redirect_cmd touch but_the_command_is_still_run 

(Wenn alles, was Sie tun müssen, mit diesem Echo ist, können Sie natürlich auch die Funktion einfacher machen, nur das erste Argument Echo statt sie alle als Befehl ausgeführt wird)

+0

Ich mag diese Lösung. "Echo" war nur ein Beispiel. Ich hätte mir einen besseren aussuchen können. –

+1

Das Beispiel ist falsch; Verwende '" $ @ "', nicht '$ @'. – vladr

+0

@Vlad: Ups. Ich weiß nicht, was mit meinem üblichen obsessiven Zitaten passiert ist. Bearbeitet! – Cascabel

2

Nicht perfekt, aber wie wäre es entweder auf Einstellung umleiten "/ dev/null" oder "/ dev/tty", und dann

{ 
    echo "verbose" 
    .... 
} > $redirect 
+4

'/ dev/stdout', nicht'/dev/tty'. Die Verwendung des letzteren führt immer dazu, dass es zur Anzeige geht, selbst wenn das Skript umgeleitet wird. –

5

tun habe die Idee von another question:

#!/bin/sh 

if [ $SILENT ]; then 
    exec &>/dev/null 
fi 

echo "Silence here." 
+1

Dieser Test für Ihr if wird Fehler geben, wenn SILENT der leere String ist. – Cascabel

+2

'if [-n" $ SILENT "]' –

0

Überlegen Sie, ob es würde lohnt sich die Einstellung set -x für detaillierte Protokollierung auf stderr im ausführlichen Modus. Wenn das so ist, kann eine Nur-Verbal-Ausgabe mit einem No-Op : wie folgt erreicht werden.

while getopts "v" o 
do case "$o" in 
    v) set -x;; 
    esac 
done 

echo "This will always be output"   # goes to stdout 
: this will only be output in verbose mode # goes to stderr 

: wertet es Argumente gibt aber nichts mit ihnen. set -x zeigt, was bei stderr ausgewertet wurde, während jede Anweisung ausgeführt wird.

Sie können auch verbose und Standard-Logs nach Stream teilen.

Vielleicht nicht, was Sie hier brauchen, aber es kann ein handlicher Trick sein.

Verwandte Themen