Wie kann ich ein Shell-Skript profilieren?

10

Ich habe mehrere Programme, die ich in einem Shell-Skript ausführe:

./myprogram1
./myprogram2
...

Ich weiß, dass ich jedes einzelne Programm durch Bearbeiten des Quellcodes profilieren kann, aber ich wollte wissen, ob es eine Möglichkeit gibt, die Gesamtzeit zu messen, die durch Profilierung des Skripts selbst ausgeführt wird. Gibt es ein Timer-Programm, das ich für diesen Zweck verwenden kann? Wenn ja, wie genau ist die Messung?

Paul
quelle
Vielleicht ist dies eine hilfreiche Profilerstellung. - Wie kann ein Bash-Shell-Skript profiliert werden? - Stapelüberlauf
Mohammad Efazati

Antworten:

10

Verwenden Sie zunächst die Zeit gemäß Jon Lins Vorschlag:

$ time ls test
test

real    0m0.004s
user    0m0.002s
sys     0m0.002s

Sie sagen nicht, auf welchem ​​Unix Ihre Skripte ausgeführt werden, sondern verwenden Linux, Truss unter Solaris / AIX, und ich denke, mit Tusc unter HP-UX können Sie viel darüber lernen, was ein Prozess tut. Ich mag die Option -c von strace, um eine schöne Zusammenfassung zu erhalten:

]$ strace -c ls
test
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 89.19    0.000998         998         1           execve
 10.81    0.000121         121         1           write
  0.00    0.000000           0        12           read
  0.00    0.000000           0        93        79 open
  0.00    0.000000           0        16           close
  0.00    0.000000           0         2         1 access
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         4           munmap
  0.00    0.000000           0         1           uname
  0.00    0.000000           0         6           mprotect
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0        30           mmap2
  0.00    0.000000           0         8         7 stat64
  0.00    0.000000           0        13           fstat64
  0.00    0.000000           0         2           getdents64
  0.00    0.000000           0         1           fcntl64
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_thread_area
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           socket
  0.00    0.000000           0         1         1 connect
------ ----------- ----------- --------- --------- ----------------
100.00    0.001119                   205        88 total

Beachten Sie auch, dass das Anhängen dieser Programme vom Typ Ablaufverfolgung das Programm etwas verlangsamen kann.

Davey
quelle
Eigentlich benutze ich meistens Redhat, aber ich fange heutzutage auch an, Debian (Ubuntu) öfter zu benutzen.
Paul
4

Überprüfen Sie den timeBefehl . Sie können es verwenden, um die Ausführungszeit zusammen mit einigen anderen nützlichen Informationen zu messen, z. B. wo die Zeit verbracht wird.

Jon Lin
quelle
2

Es ist nicht gerade eine Profilerstellung, aber Sie können Ihr Skript während der Ausführung verfolgen. Setzen Sie set -xvvor dem Abschnitt, den Sie verfolgen möchten, und set +xvnach dem Abschnitt. set -xaktiviert xtrace, das jede ausgeführte Zeile anzeigt. set -vAktiviert den ausführlichen Modus, in dem auch Zeilen angezeigt werden, die möglicherweise Auswirkungen haben, aber nicht ausgeführt werden, z. B. die Variablenzuweisung.

Sie können Ihre Ablaufverfolgung auch mit einem Zeitstempel versehen. Sie benötigen einen Terminalemulator, der jede Zeile mit einem Zeitstempel versehen kann. Das einzige, das ich kenne, ist RealTerm , ein Windows-Programm, das jedoch mit Wine funktioniert. Möglicherweise können Sie es auch verwenden grabserial, obwohl ich es nur mit echten seriellen Schnittstellen ausprobiert habe. Sie können herausfinden, welches serielle Gerät Ihre Shell verwendet, indem Sie es ausführen ps -p $$(wenn dies nicht der Fall ist man, erfahren Sie, wie Sie die TTY-Spalte in Ihre psAusgabe aufnehmen können).

Auch hierzu finden Sie Performance - Profiling - Tools für Shell - Skripte auf Stack - Überlauf.

Shawn J. Goff
quelle
1

time für mehrere Iterationen

Profilerstellung durch mehrmaliges Ausführen desselben Befehls

time (for ((n=0;n<10;n++)); do echo "scale=1000; 4*a(1)" | bc -l; done)

Wobei echo "scale=1000; 4*a(1)" | bc -lpi berechnet und time (...)sichergestellt wird, dass die forSchleife als einzelner Befehl ausgeführt wird.

Anton Tarasenko
quelle
0

Da ich jetzt mindestens zweimal hier gelandet bin, habe ich eine Lösung implementiert:

https://github.com/walles/shellprof

Es führt Ihr Skript aus, taktet transparent alle gedruckten Zeilen und druckt am Ende eine Top-10-Liste der Zeilen, die am längsten auf dem Bildschirm angezeigt wurden:

~/s/shellprof (master|✔) $ ./shellprof ./testcase.sh
quick
slow
quick

Timings for printed lines:
1.01s: slow
0.00s: <<<PROGRAM START>>>
0.00s: quick
0.00s: quick
~/s/shellprof (master|✔) $
Johan Walles
quelle