1299 Stimmen

Wie man Shell-Befehle bei der Ausführung echot, wenn sie ausgeführt werden

Wie kann ich in einem Shell-Skript alle aufgerufenen Shell-Befehle als Echo ausgeben und alle Variablennamen erweitern?

Ein Beispiel ist die folgende Zeile:

ls $DIRNAME

Ich möchte, dass das Skript den Befehl ausführt und das Folgende anzeigt

ls /full/path/to/some/dir

Der Zweck ist, ein Protokoll aller aufgerufenen Shell-Befehle und ihrer Argumente zu speichern. Gibt es vielleicht eine bessere Möglichkeit, ein solches Protokoll zu erstellen?

1477voto

Tom Punkte 41522

set -x o set -o xtrace erweitert die Variablen und druckt ein kleines + Zeichen vor der Zeile.

set -v o set -o verbose expandiert die Variablen vor dem Drucken nicht.

Utilice set +x y set +v um die oben genannten Einstellungen zu deaktivieren.

In der ersten Zeile des Skripts kann man Folgendes eingeben #!/bin/sh -x (oder -v ) die gleiche Wirkung haben wie set -x (oder -v ) später im Drehbuch.

Das obige funktioniert auch mit /bin/sh .

Siehe das Wiki der bash-hackers auf set Eigenschaften und am Fehlersuche .

$ cat shl
#!/bin/bash                                                                     

DIR=/tmp/so
ls $DIR

$ bash -x shl 
+ DIR=/tmp/so
+ ls /tmp/so
$

450voto

radman Punkte 16284

set -x wird Ihnen geben, was Sie wollen.

Hier ist ein Beispiel-Shell-Skript zur Veranschaulichung:

#!/bin/bash
set -x #echo on

ls $PWD

Dies erweitert alle Variablen und gibt die vollständigen Befehle vor der Ausgabe des Befehls aus.

Ausgabe:

+ ls /home/user/
file1.txt file2.txt

136voto

Soth Punkte 2541

Ich verwende eine Funktion zum Echo und zur Ausführung des Befehls:

#!/bin/bash
# Function to display commands
exe() { echo "\$ $@" ; "$@" ; }

exe echo hello world

Welche Ausgaben

$ echo hello world
hello world

Für kompliziertere Befehle, Pipes usw. können Sie eval verwenden:

#!/bin/bash
# Function to display commands
exe() { echo "\$ ${@/eval/}" ; "$@" ; }

exe eval "echo 'Hello, World!' | cut -d ' ' -f1"

Welche Ausgaben

$  echo 'Hello, World!' | cut -d ' ' -f1
Hello

103voto

shuckc Punkte 2585

Sie können dies auch für ausgewählte Zeilen in Ihrem Skript einschalten, indem Sie sie in set -x y set +x zum Beispiel,

#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
   echo "grabbing $URL"
   set -x
   curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
   set +x
fi

82voto

bhassel Punkte 861

shuckc's Antwort für das Echo ausgewählter Zeilen hat ein paar Nachteile: Sie erhalten folgende Ergebnisse set +x Befehl wird auch als Echo ausgegeben, und Sie verlieren die Möglichkeit, den Exit-Code mit $? überschrieben wird, da sie von der set +x .

Eine andere Möglichkeit ist, den Befehl in einer Subshell auszuführen:

echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )

if [ $? -eq 0 ] ; then
    echo "curl failed"
    exit 1
fi

was zu einer Ausgabe wie dieser führt:

getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed

Dabei entsteht allerdings der Overhead, eine neue Subshell für den Befehl zu erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X