2016-04-24 7 views
5

sehe ich bin mitLassen DEBUG Bash Falle Rohr als ein Befehl

trap 'echo -e "\e[92m$ $BASH_COMMAND\e[0m"' DEBUG 

in einem Bash-Skript jeden Befehl zu drucken, die ausgeführt wird.

Dies funktioniert gut, außer dass es druckt zwei Befehle, wenn ich Rohr sie zusammen:

bzip2 -dc < dump.sql.bz2 | mysql test 

Drucke:

$ bzip2 -dc < dump.sql.bz2 
$ mysql test 

Kann ich jede Änderung an der trap oder machen die Linie mit dem Rohr, so dass die Linie als eine gedruckt wird?

Antwort

2

Ihren Befehl ändern:

mysql test < <(bzip2 -dc < dump.sql.bz2) 

ein process substitution statt einer Pipeline Mit dem Befehl einen einfacher Befehl von Bash Sicht macht, die das Niveau der Granularität ist, an den die DEBUG Falle und die integrierte in $BASH_COMMAND variabel betreiben.

Hintergrund:

Die DEBUG (pseudo) Signal, das durch Design auf der Ebene der einfachen Befehlen arbeitet, wie $BASH_COMMAND tut.

bzip2 -dc < dump.sql.bz2 | mysql test ist eine Pipeline bestehend aus mehrere einfache Befehle.

Daher kann Ihre trap Anweisung nicht tun, was Sie wollen mit einer Pipeline.

Die nächste Sache zu bekommen, was Sie mit einem Verbindung Befehlen wollen (zB eine while Schleife oder eine Befehlsgruppe ({ ...; ...; }) oder ein Befehl Liste (einfache Befehle oder Rohrleitungen mit den Betreibern verbunden ; && || &) verwenden set -v, die den gesamten Befehl stderr Echos, bevor er ausgeführt wird, aber ich würde nicht wissen, wie die Formatierung dieser Ausgabe steuern

+0

Hat bash * müssen * über die Pipeline wissen? Kann ich die Rohrleitung nicht an irgendeine Art von Werkzeug delegieren, so dass es aus der Sicht von bash ein einziger Befehl ist? – AndreKR

+0

Sie können die Pipeline in eine _function_ platzieren, und dann wird der Aufruf dieser Funktion ein Befehl _simple_ aus Bashs Perspektive sein - aber das wird auch die tatsächliche Pipeline von Ihnen verbergen. – mklement0

+0

Es akzeptiert keine Dateinamen, aber 'mysql test <<(bzip2 -dc AndreKR

1

eine grobe Abhilfe eine Funktion wäre verwenden, wie folgt aus:.

run() { eval $1; } 
trap 'echo -e "\e[92m$ $BASH_COMMAND\e[0m"' DEBUG 
run "bzip2 -dc < dump.sql.bz2 | mysql test" 

Ausgang:

$ run "bzip2 -dc < dump.sql.bz2 | mysql test" 
+0

++; Sehr schlau - und sicher, solange Sie die Befehlsfolge vollständig kontrollieren. – mklement0

+1

'$ 1' ist der Parameter der * Funktion *, daher würde ich annehmen, dass dies immer genauso sicher ist wie der ursprüngliche Befehl, der nun als Parameter der Funktion zugeführt wird. – AndreKR

+0

Völlig einverstanden - Ich wollte nur Bedenken beseitigen, die zukünftige Leser aufgrund der Verwendung von 'eval' haben könnten, was normalerweise rote Fahnen hervorruft (und Sie haben es besser formuliert). – mklement0