2010-05-18 19 views
536

W skrypcie powłoki, w jaki sposób wywołać echo wszystkich poleceń powłoki, które wywołują i rozszerzają nazwy zmiennych? Na przykład, biorąc pod uwagę następujący wiersz:W skrypcie powłoki: komendy powłoki echo, gdy są wykonywane

ls $DIRNAME 

Chciałbym skrypt, aby uruchomić polecenie i wyświetlić następujące

ls /full/path/to/some/dir 

celem jest, aby zapisać dziennik wszystkich poleceń powłoki o nazwie i ich argumenty. Być może istnieje lepszy sposób na wygenerowanie takiego dziennika?

Odpowiedz

598

set -x lub set -o xtrace rozwija zmienne i wypisuje mały znak + przed linią.

set -v lub nie rozwija zmiennych przed drukowaniem.

Użyj przycisków set +x i set +v, aby wyłączyć powyższe ustawienia.

Na pierwszej linii skryptu, można umieścić #!/bin/sh -x (lub -v), aby mieć taki sam skutek jak set -x (lub -v) później w skrypcie.

Powyższe działa również z /bin/sh.

http://www.faqs.org/docs/abs/HTML/options.html

$ cat shl 
#!/bin/bash                  

DIR=/tmp/so 
ls $DIR 

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

set -x da ci to, czego chcą.

Oto przykład skrypt wykazać:

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

ls $PWD 

Rozszerza wszystkie zmienne i drukuje pełne komendy przed wyjściem polecenia.

wyjściowa:

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

Używając słowa "gadatliwy" w ten sposób niczego nie osiągnąć. Możesz zrobić "set -o verbose" lub "set -v" (tylko "verbose") lub 'set -o xtrace' lub' set -x' (tylko "xtrace") lub 'set -xv' (both) lub 'set -o xtrace -o verbose' (oba). –

+0

działa to dobrze, ale należy pamiętać, że "verbose" powoduje nadpisanie $ 1 – JasonS

+0

@ jasonS *. Ale tak, nie pomyślałem o tym, dobry – Wyatt8740

67

Można również włączyć ten na wybranych liniach w skrypcie przez owijanie ich w set -x i set +x np

#!/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 
27

Inną opcją jest umieszczenie "-x" na górze skryptu zamiast w wierszu poleceń: (. Niewystarczająca rep komentować wybraną odpowiedź)

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

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

+0

Zauważ, że to nie wydaje się działać dokładnie tak samo pomiędzy './MyScript' i' bash myScript'. Wciąż dobrze jest wskazać, dzięki. – altendky

3

dla zsh echo

setopt VERBOSE 

i do debugowania

Odpowiedź
setopt XTRACE 
34

shuckc za echem linii wyboru ma kilka wad: skończyć się za pomocą następującego polecenia set +x echem jest także, i tracisz możliwość przetestowania kod wyjścia z $? ponieważ zostaną nadpisane przez set +x.

Inną opcją jest uruchomienie komendy w podpowłoce:

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

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

która daje wyjście jak:

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

to robi ponieść napowietrznej tworzenia nowej powłoki w tle dla polecenia, chociaż.

+6

Dobry sposób na uniknięcie wyjścia '++ set + x'. –

+2

Jeszcze lepiej: zamień 'if [$? -eq 0] 'with' if (set -x; COMMAND) '. –

14

Wpisz "bash -x" w wierszu poleceń przed nazwą skryptu bash. Na przykład, aby wykonać foo.sh, typ:

bash -x foo.sh 
55

używać funkcji echo następnie uruchomić komendę

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

exe echo hello world 

które wyjścia

$ echo hello world 
hello world 

Edit:

Aby uzyskać bardziej skomplikowane polecenia, możesz użyć eval:

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

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

które wyjścia

$ echo 'Hello World' | cut -d ' ' -f1 
Hello 
+0

Za mało głosów dla tej odpowiedzi. Czy jest jakiś powód, dla którego jest to zły pomysł? Pracował dla mnie i wydaje się być dokładnie tym, czego szukam ... – fru1tbat

+1

To jest najlepsza odpowiedź, jeśli nie chcesz, aby każde polecenie zostało wydrukowane. Pozwala uniknąć wyjścia '++ set + x', gdy jest wyłączone, a także wygląda czystsze. Jednak dla pojedynczego zdania lub dwóch, odpowiedź bhassel za pomocą podpórki jest najwygodniejsza. –

+0

Tego właśnie szukam! Nie "ustaw + x", wpływa na wszystkie polecenia, czyli za dużo! – Hlung

2

Dla csh i tcsh można set verbose lub set echo (lub można nawet ustawić oba, ale może to spowodować w pewnym powielania przez większość czasu).

W verbose opcja drukuje dość dużo dokładna shell wyrażenie, które wpiszesz.

Opcja echo jest bardziej wskazują na to, co będzie realizowany poprzez tarła.


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.

1

Aby umożliwić powtarzanie komend złożonych, używam funkcji eval oraz funkcjiSotha do echa, a następnie uruchomienia polecenia. Jest to użyteczne w przypadku potokowych poleceń, które w przeciwnym razie wyświetlałyby tylko none lub tylko początkową część polecenia piped.

Bez eval:

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

Wyjścia:

$ 
file.txt 

Z eval:

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

które wyjścia

$ exe eval 'ls -F | grep *.txt' 
file.txt 
14

Według TLDP „s Bash Guide for Beginners: Chapter 2. Writing and debugging scripts

2.3.1. Debugowanie na całym skrypcie

$ bash -x script1.sh 

...

Jest teraz pełnoprawnym debugger dla Basha, dostępny na SourceForge. Te funkcje debugowania są dostępne w większości nowoczesnych wersji Bash, począwszy od wersji 3.x.

2.3.2. Debugowanie na części (-ach) skryptu

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

...

Tabela 2-1. Przegląd ustawić opcje debugowania

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. 

...

Alternatywnie, te tryby mogą być określone w samym skrypcie przez dodając żądane opcje do pierwszej deklaracji linia kadłuba. opcje można łączyć, jak to zwykle bywa z UNIX poleceń:

#!/bin/bash -xv 
1
$ cat exampleScript.sh 
#!/bin/bash 
name="karthik"; 
echo $name; 

bash -x exampleScript.sh 

wyjścia jest następujący:

enter image description here

4

Ktoś wyżej pisał:

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

i tym ooki obiecujące, ale nie mogę dla mojego życia dowiedzieć się, co robi. Mam wpisane przeze mnie hasło i szukam na stronie man bash dla "\ $" i "$ @", i znajduję absolutnie nic nie jest.

Rozumiem, że tworzona jest funkcja o nazwie "exec()". Rozumiem, że nawiasy klamrowe oznaczają początek i koniec funkcji.Myślę, że rozumiem, że średnik oznacza "twardy powrót" między poleceniem wieloliniowym, więc "{echo" \ $ $ @ "; "$ @"; }”Staje się w istocie:

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

} 

Może ktoś mi dać krótkie wyjaśnienie, lub gdzie znaleźć te informacje, ponieważ oczywiście moje google-fu zawodzi mnie?

(Bez znaczenia, aby rozpocząć nowe pytanie w starym wątku, moim celem jest przekierowanie danych wyjściowych do pliku. "Metoda set -x; [commands]; set + x" działałaby dobrze dla mnie, ale nie mogę dowiedzieć się, jak echo wyników do pliku zamiast ekranu, więc starałem się zrozumieć tę inną metodę w nadziei, że mogę użyć mnie bardzo słabe zrozumienie przekierowania/pipes/tee/etc, aby zrobić to samo rzecz.)

Dzięki!

PÓŹNIEJ EDIT:

Z pewnym majsterkowania, wierzę zdobione. Oto mój odpowiednik kod co mam potrzeby:

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 

Wyniki w wyglądać logfile.txt jak:

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 

Tylko to, co potrzebne. Dzięki!

+0

Wierzę, że to wymyśliłem. Oto mój odpowiednik kod co mam potrzeby: exe ​​() { params = "$ @" \t \t \t \t \t \t # umieścić wszystkie wiersza polecenia w "params" printf „% s \ t $ params " "$ (data)" >> "$ SCRIPT_LOG" \t # wypisuje polecenie do pliku dziennika $ params \t \t \t \t \t \t \t # Wykonaj polecenie} \t exe ​​rm -rf/Library/LaunchAgents/com .carbonite.launchd.carbonitealerts.plist \t exe ​​rm -rf /Library/LaunchAgents/com.carbonite.launchd.carbonitestatus.plist – DebianFanatic

+0

Potrzebuje \ n, aby przerwać linię w 'printf"% s \ t $ params "" $ (data) ">>" $ SCRIPT_LOG "' – user3762200

3

Można wykonać skrypt bash w trybie debugowania z opcję -x.
Powtórzy to wszystkie polecenia.

bash -x example_script.sh 

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


Można również zapisać opcję -x w skrypcie. Po prostu określ opcję -x w shebangu.

######## 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 



Powiązane problemy