Dtrace One-Liners Made Easy
I ain't typin' all that crap neither
May 12, 2007
Every once in a while I troll a blog with a good DTrace one-liner. Useful as they are, they're also as digestible and memorable on first sight as a so-called cool Perl hack. I refer to these incantations when I teach but I can tell when I hear no student typing that they aren't fooled by the implication of ease when they see:

# dtrace -n 'sched:::on-cpu { @[execname, pid] = count() }'

or something much longer. I know from experience that repetition and practice makes writing out one-liners easier, of course. First, however, you have to convince a skeptical student to try one. To stay interested, most need a meaningful result quickly. Also, while the lazy practitioner might want a better way to remember the syntax, it's even better if you can just make the computer do the work.

So here's a kludge for remembering a series of DTrace favorites using the Korn shell. This technique is generally useful for any amount of repeated command-line work, but it seems most appropriate for a series of related tools.

First, name a function in your shell script that declares the purpose of the enclosed one-liner:

# System call count by process
function syscall_count_by_process
{
   echo "Syscall count by program"
   echo "dtrace -n 'syscall:::entry { @num[execname] = count(); }'"
   dtrace -n 'syscall:::entry { @num[execname] = count(); }'
}

When called, this function will echo its purpose and the line it will execute. In this case, the one-liner fires upon entering any system call. It then counts each one, collecting the results by the calling process's name.

Any number of functions written this same way could be added to a script. It's a good idea to include a function for leaving the shell script too:

# Exit the select loop
function Quit
{
   echo "Thanks for trying out the one-liners!"
   exit
}

Now the fun. Using a select structure, the main script indexes the available functions by calling typeset +f, which lists all functions loaded in the shell's memory. The user then selects a function by its index and runs it:

PS3="Select a one-liner (RETURN refreshes list): "

select one_liner in `typeset +f`
do
   echo
   trap "trap '' 2" 2
   echo '***********************'
   ${one_liner}
   trap "" 2
   echo '***********************'
done

Once the selection is made, the loop sets a trap that will prevent the script from exiting when the user types ^C to terminate the one-liner. It's an old trick lifted directly from the /etc/login file in Solaris, used to prevent a user from breaking out of environment initialization after authenticating.

Because the indexed name is the function name itself, the script can invoke the function simply by calling ${one_liner}. Not a robust approach, but a very easy one to implement.

This script already contains 15 one-liners written as functions. Try them and see what results you get. It's not at all a robust solution, but it doesn't take long to whip one up and its easy to build. It's also a trivial matter to invoke whole D programs too, like the ones in /usr/demo/dtrace. Trivial, as in get on it. Chop chop!


hi, not only the cool one liners are very helpful, but also the typeset -f which creates the index. I didn't know that one, thanks a lot. Regards, Moritz
This is superb! Thanks for the good work. The "typeset -f" idea is very well used here and I am now trying to implement the same thing in many more automation at my side.
Great !


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 1 + 1 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/michael/addTrackBack.action?entry=1179024386769