How can I profile a shell script?
Start by using time as per Jon Lin's suggestion:
$ time ls test
test
real 0m0.004s
user 0m0.002s
sys 0m0.002s
You don't say what unix your scripts are running on but strace on linux, truss on Solaris/AIX, and I think tusc on hp-ux let you learn a lot about what a process is doing. I like strace's -c option to get a nice summary:
]$ 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
Do also note that attaching these tracing type programs can slow the program down somewhat.
Check out the time
command. You can use it to measure the time it takes to execute along with some other useful info like where the time is being spent.
It's not exactly profiling, but you can trace your script as it runs. Put set -xv
before the section you want to trace and set +xv
after the section. set -x
enables xtrace, which will show every line that executes. set -v
enables verbose mode, which will also show lines that may have an effect, but are not executed, such as variable assignment.
You can also timestamp your trace. You need a terminal emulator that can timestamp every line; the only one I know of is RealTerm, which is a Windows program, but it will work with Wine. You might also be able to use grabserial
, although I've not tried it except with real serial ports. You can find out what serial device your shell is using by running ps -p $$
(if it doesn't, use man
to find out how to include the TTY column in your ps
output).
Also, see Performance profiling tools for shell scripts on Stack Overflow.