4.1.3.5 system (Process-Destructive)

void system(string program, ...)

The system action causes the specified program to be executed as though given to the shell as input. The program string can contain any of the printf or printa format conversions. Arguments that match the format conversions must be specified. See Chapter 6, Output Formatting for details on valid format conversions.

The following example runs the date command once per second:

# dtrace -wqn tick-1sec'{system("date")}'
Tue Oct 16 10:21:34 BST 2012
Tue Oct 16 10:21:35 BST 2012
Tue Oct 16 10:21:36 BST 2012
^C
#

The following example shows a more elaborate use of the action by using printf conversions in the program string, along with traditional filtering tools such as pipes. Type the following source code and save it in a file named whosend.d:

#pragma D option destructive
#pragma D option quiet

proc:::signal-send
/args[2] == SIGINT/
{
  printf("SIGINT sent to %s by ", args[1]->pr_fname);
  system("getent passwd %d | cut -d: -f5", uid);
}

Running the previous script results in output similar to the following:

# dtrace -s whosend.d
SIGINT sent to top by root
SIGINT sent to bash by root
SIGINT sent to bash by A Nother
^C
SIGINT sent to dtrace by root

The execution of the specified command does not occur in the context of the firing probe. Rather, it occurs when the buffer containing the details of the system action are processed at user level. How and when this processing occurs depends on the buffering policy, as described in Chapter 5, Buffers and Buffering. With the default buffering policy, the buffer processing rate is specified by the switchrate option.

You can see the delay that is inherent in system if you explicitly tune the switchrate higher than its one-second default, as shown in the following example. Save it in a file named time.d:

#pragma D option quiet
#pragma D option destructive
#pragma D option switchrate=5sec

tick-1sec
/n++ < 5/
{
  printf("walltime : %Y\n", walltimestamp);
  printf("date : ");
  system("date");
  printf("\n");
}

tick-1sec
/n == 5/
{
  exit(0);
}

Running the previous script results in output similar to the following:

# dtrace -s time.d
walltime : 2012 Oct 16 10:26:07
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:08
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:09
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:10
date : Tue Oct 16 10:26:11 BST 2012

walltime : 2012 Oct 16 10:26:11
date : Tue Oct 16 10:26:11 BST 2012

In the previous output, notice that the walltime values differ, but the date values are identical. This result reflects the fact that the execution of the date command occurred when the buffer was processed, not when the system action was recorded.