[Solaris] 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 like to refer to these incantations when I teach; however, I can tell by the absence of subsequent typing that students 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, one has to convince a skeptical student to try one. For most to stay interested, they want a meaningful result quickly. Also, the lazy practitioner (ahem) will want a better way to remember yet another command-line syntax: make the computer do it.

So here's a kludge for remembering a series of Dtrace favorites, using Korn shell functions. The technique is useful for any tedious command-line work, really, but it seems most appropriate for a series of related tools which may run arbitrarily long.

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.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 4 + 7 = (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