2013-03-12 8 views
6

Ich schreibe ein Bash-Skript, wo ich möchte, dass alle Befehle, wie sie auftreten, echoed werden. Ich weiß, dass ich set -x und set +x verwenden muss, um dieses Verhalten ein- bzw. auszuschalten (SOF post here). Es gibt jedoch nicht alles wieder, nämlich E/A-Weiterleitungen.Bash-Set -x-Echo-Weiterleitungen sowie Befehle

Zum Beispiel lassen Sie uns sagen, dass ich diese sehr einfache Bash-Skript haben:

set -x 
./command1 > output1 
./command2 arg1 arg2 > output2 

Dies wird der Ausgang

+ ./command1 
+ ./command2 arg1 arg2 

Bash ist nicht meine stdout Echo umleiten zu output1 und output2. Warum ist das? Wie kann ich dieses Verhalten erreichen? Vielleicht gibt es eine shopt Option, die ich im Skript einstellen muss?

HINWEIS: Ich bemerkte auch, dass Rohre nicht wie erwartet gedruckt werden. Zum Beispiel, wenn ich diesen Befehl verwenden waren:

set -x 
./command3 | tee output3 

werde ich diese Ausgabe erhalten:

+ tee output3 
+ ./command3 

Wie mache ich die Befehle in der Art und Weise wider genau werden sie geschrieben werden, anstatt die des Habens Rohr nach dem Skript neu geordnet?

Antwort

4

Es ist nicht möglich mit set -x. Ihre einzige Option ist, den aktuellen Befehl über eine DEBUG Trap anzuzeigen.

trap 'printf %s\\n "$BASH_COMMAND" >&2' DEBUG 

Dies wird die genauen Argumente als set -x Willen nicht zeigen. Kombinieren sie Ihnen das vollständige Bild, obwohl es eine Menge Debug-Ausgabe ist.

+0

Aber was ist mit FreeBSD System? Weil ich einen solchen Trick dort wegen des Fehlens des DEBUG-Signals nicht machen kann. Irgendwelche Vorschläge? – vwvolodya

5

Weder set -x noch die DEBUG-Trap bieten vollständige Informationen, wenn bestimmte Konstrukte verwendet werden.

Beispiele sind:

ex1.sh

for i in a b c 
do 
    echo $i # Where does the output go? 
done > outfile # Here! 

ex2.sh

c="this" 
case "$c" in 
    this) echo sure ;; # Where does the output go? 
    that) echo okay ;; 
esac > choice # Here! 

ex3.sh

what="up" 
while [ "$what" = "up" ] 
do 
    echo "Going down!" # Where does the output go? 
    what="down" 
    echo "Newton rulezzz!" > thelaw 
done > trying # Here! 

und viele wie diese mehr, geschweige denn alle Arten von verschachtelten Varianten. Ich kenne keine einfache Möglichkeit, diese zu behandeln, außer in das Land der vollen Bash-Skript-Parsing, die ein Minenfeld ist ...

EDIT: Wenn Bash-spezifische Funktionen nicht erforderlich sind, und Abwärtskompatibilität mit dem Bourne-Shell tun wird, funktioniert der Korn-Shell (ksh, getestet mit Version 93u + 2012-08-01) besser ein bisschen auf Informationen für Umleitungen zeigen:

$ ksh -x ex1.sh 
+ 1> outfile 
+ echo a 
+ echo b 
+ echo c 

$ ksh -x ex2.sh 
+ c=this 
+ 1> choice 
+ echo sure 

$ ksh -x ex3.sh 
+ what=up 
+ 1> trying 
+ [ up '=' up ] 
+ echo 'Going down!' 
+ what=down 
+ echo 'Newton rulezzz!' 
+ 1> thelaw 
+ [ down '=' up ] 
3

Sie eher set -v verwenden sollten.

-v Drucken Shell Eingangsleitungen, wie sie gelesen werden.

Die Ausgabe scheint Ihre Erwartungen zu erfüllen.

$ set -v 
$ ./command1 > output1 
./command1 > output1 
sh: ./command1: No such file or directory 
$ ./command2 arg1 arg2 > output2 
./command2 arg1 arg2 > output2 
sh: ./command2: No such file or directory 
$ ./command3 | tee output3 
./command3 | tee output3 
sh: ./command3: No such file or directory 
+0

Dies funktionierte perfekt für mich und scheint die beste Antwort auf diese Frage zu sein. Danke dafür. – Nickolai

+0

Beachten Sie, dass dies bei komplexeren Bash-Skripten mit Funktionen nicht funktioniert, da die Eingaben in diesen Fällen nur einmal gelesen werden. –