it-swarm.com.de

So geben Sie Shell-Befehle zurück, wenn sie ausgeführt werden

Wie kann ich in einem Shell-Skript alle aufgerufenen Shell-Befehle wiedergeben und Variablennamen erweitern?

Zum Beispiel mit der folgenden Zeile:

ls $DIRNAME

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

ls /full/path/to/some/dir

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

768
Jack Nock

set -x oder set -o xtrace erweitert Variablen und gibt ein kleines + -Zeichen vor der Zeile aus.

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

Verwenden Sie set +x und set +v, um die obigen Einstellungen zu deaktivieren.

In die erste Zeile des Skripts kann #!/bin/sh -x (oder -v) gesetzt werden, um den gleichen Effekt wie set -x (oder -v) später im Skript zu erzielen.

Das oben Genannte funktioniert auch mit /bin/sh.

Siehe das Bash-Hacker-Wiki unter set attributes und debugging .

$ cat shl
#!/bin/bash                                                                     

DIR=/tmp/so
ls $DIR

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

set -x gibt dir, was du willst.

Hier ist ein Beispiel für ein Shell-Skript:

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

ls $PWD

Dies erweitert alle Variablen und gibt die vollständigen Befehle aus, bevor der Befehl ausgegeben wird.

ausgabe:

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

Sie können dies auch für ausgewählte Zeilen in Ihrem Skript umschalten, indem Sie sie in set -x und set +x einschließen, z.

#!/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
82
shuckc

Ich benutze eine Funktion, um das Echo dann den Befehl auszuführen

#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }

exe echo hello world

Welche Ausgänge

$ echo hello world
hello world

Bearbeiten:

Für kompliziertere Kommandopipes etc. können Sie eval benutzen:

#!/bin/bash
#function to display commands
exe() { echo "\$ ${@/eval/}" ; "[email protected]" ; }

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

Welche Ausgänge

$  echo 'Hello World' | cut -d ' ' -f1
Hello
74
Soth

die Antwort von shuckc für das Echo ausgewählter Zeilen hat einige Nachteile: Es wird auch der folgende Befehl set +x ausgegeben, und Sie verlieren die Möglichkeit, den Beendigungscode mit $? zu testen, da er vom überschrieben wird set +x.

Eine andere Möglichkeit besteht darin, 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 gibt Ihnen die Ausgabe wie:

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

Dies ist jedoch mit dem Aufwand verbunden, eine neue Subshell für den Befehl zu erstellen.

48
bhassel

Eine andere Möglichkeit besteht darin, "-x" anstelle der Befehlszeile oben in Ihr Skript einzufügen:

$ cat ./server
#!/bin/bash -x
ssh [email protected]

$ ./server
+ ssh [email protected]
[email protected]'s password: ^C
$

(Nicht genügend Mitarbeiter, um die gewählte Antwort zu kommentieren.)

33
nooj

Gemäß TLDP 's Bash-Anleitung für Anfänger: Kapitel 2. Skripten schreiben und debuggen

2.3.1. Debuggen des gesamten Skripts

$ bash -x script1.sh

...

Es gibt jetzt einen vollwertigen Debugger für Bash, verfügbar unter SourceForge . Diese Debugging-Funktionen sind in den meisten modernen Versionen von Bash ab Version 3.x verfügbar.

2.3.2. Debuggen von Teilen des Skripts

set -x            # activate debugging from here
w
set +x            # stop debugging from here

...

Tabelle 2-1. Übersicht der eingestellten Debugging-Optionen

Short  | Long notation | Result  
-------+---------------+--------------------------------------------------------------
set -f | set -o noglob | Disable file name generation using metacharacters (globbing).  
set -v | set -o verbose| Prints Shell input lines as they are read.  
set -x | set -o xtrace | Print command traces before executing command.  

...

Alternativ können diese Modi im Skript selbst angegeben werden, indem die gewünschten Optionen zur Shell-Deklaration in der ersten Zeile hinzugefügt werden. Optionen können kombiniert werden, wie dies normalerweise bei UNIX-Befehlen der Fall ist:

#!/bin/bash -xv
19
Afriza N. Arief

Geben Sie "bash -x" in die Befehlszeile vor dem Namen des Bash-Skripts ein. Um beispielsweise foo.sh auszuführen, geben Sie Folgendes ein:

bash -x foo.sh
17
Alan

Sie können ein Bash-Skript im Debug-Modus mit der Option - xausführen.
Dadurch werden alle Befehle wiedergegeben.

bash -x example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt


Sie können auch speichern Sie die Option -x im Skript. Geben Sie einfach die Option -x im Shebang an.

######## example_script.sh ###################
#!/bin/bash -x

cd /home/user
mv text.txt mytext.txt

##############################################

./example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt



8
RenRen

Jemand oben geschrieben:

#!/bin/bash
#function to display commands
exe() { echo "\$ [email protected]" ; "[email protected]" ; }

und das sieht vielversprechend aus, aber ich kann für mein ganzes Leben nicht herausfinden, was es tut. Ich habe in der Man-Bash-Seite nach "\ $" und "$ @" gegoogelt und gesucht und finde absolut nichts.

Ich verstehe, dass eine Funktion mit dem Namen "exec ()" erstellt wird. Ich verstehe, dass die geschweiften Klammern den Anfang und das Ende der Funktion markieren. Ich denke, ich verstehe, dass das Semikolon eine "harte Rückkehr" zwischen einem mehrzeiligen Befehl markiert, so dass '{echo "\ $ $ @"; "$ @"; } 'wird im Wesentlichen:

{
echo "\$ [email protected]"
"[email protected]"

}

Kann mir jemand eine kurze Erklärung geben oder wo ich diese Informationen finden kann, da mein Google-Fu mir offensichtlich nicht hilft?

(Ohne die Absicht, eine neue Frage in einem alten Thread zu beginnen, besteht mein Ziel darin, die Ausgabe in eine Datei umzuleiten. Die Methode "set -x; [Befehle]; set + x" würde für mich angemessen funktionieren, aber ich kann " t herauszufinden, wie die Ergebnisse in einer Datei statt auf dem Bildschirm wiedergegeben werden, so habe ich versucht, diese andere Methode in der Hoffnung zu verstehen, ich könnte mich sehr schlecht verstehen von Umleitung/Pipes/Tee/etc, um das gleiche zu tun.)

Vielen Dank!

LATER EDIT:

Ich glaube, ich habe es mit ein bisschen Basteln herausgefunden. Hier ist mein äquivalenter Code für das, was ich brauche:

SCRIPT_LOG="\home\buddy\logfile.txt"
exe () {
  params="[email protected]"                       # Put all of the command-line into "params"
  printf "%s\t$params" "$(date)" >> "$SCRIPT_LOG"   # Print the command to the log file
  $params                           # Execute the command
}

exe rm -rf /Library/LaunchAgents/offendingfile
exe rm -rf /Library/LaunchAgents/secondoffendingfile

Die Ergebnisse in der Datei logfile.txt sehen ungefähr so ​​aus:

Tue Jun  7 16:59:57 CDT 2016  rm -rf /Library/LaunchAgents/offendingfile
Tue Jun  7 16:59:57 CDT 2016  rm -rf /Library/LaunchAgents/secondoffendingfile

Genau das, was ich brauchte. Vielen Dank!

5
DebianFanatic

Für zsh Echo

 setopt VERBOSE

und zum Debuggen

 setopt XTRACE
3
zzapper

Für csh und tcsh können Sie set verbose oder set echo (oder Sie können sogar beides einstellen, dies kann jedoch die meiste Zeit zu Duplikaten führen).

Die Option verbose gibt so ziemlich den exakten Shell-Ausdruck aus, den Sie eingeben.

Die Option echo gibt eher an, was durch das Laichen ausgeführt wird.


http://www.tcsh.org/tcsh.html/Special_Shell_variables.html#verbose

http://www.tcsh.org/tcsh.html/Special_Shell_variables.html#echo


Special Shell variables

verbose If set, causes the words of each command to be printed, after history substitution (if any). Set by the -v command line option.

echo If set, each command with its arguments is echoed just before it is executed. For non-builtin commands all expansions occur before echoing. Builtin commands are echoed before command and filename substitution, because these substitutions are then done selectively. Set by the -x command line option.

2
cnst
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;

bash -x exampleScript.sh

Die Ausgabe ist wie folgt:

enter image description here

1
Karthik Arun

Damit zusammengesetzte Befehle wiedergegeben werden können, verwende ich eval und die exe -Funktion von Soth, um den Befehl wiederzugeben und dann auszuführen. Dies ist nützlich für weitergeleitete Befehle, bei denen sonst nur keiner oder nur der erste Teil des weitergeleiteten Befehls angezeigt wird.

Ohne Bewertung:

exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe ls -F | grep *.txt

Ausgänge:

$
file.txt

Mit eval:

exe() { echo "\$ [email protected]" ; "[email protected]" ; }
exe eval 'ls -F | grep *.txt'

Welche Ausgänge

$ exe eval 'ls -F | grep *.txt'
file.txt
1
Paul Havens