SystemTap脚本的Shebang

执行SystemTap脚本时,最麻烦的就是参数。例如,要指定自己编写的Tapset路径来执行时,必须每次使用-I选项指定。有没有像shell脚本一样作为可执行文件处理的方法呢?shell文件的第一行总是以#!/bin/sh或#!/bin/bash开头。这个称为Shebang, Linux内核获得执行文件的开头,如果是以#!开头的,就会将这个文件作为参数传递给此后的可执行文件。最简单的SystemTap脚本的Shebang如下所示。


!/usr/bin/stap


这里如果指定-I选项作为参数,则变为:


!/usr/bin/stap-I tapset


但是这个方法主要存在移植性方面的两个问题。

·stap命令并不一定总是在/usr/bin下。

·Tapset的相对位置并不一定是相同目录。例如,想从上一个目录直接执行脚本时就会出错。

前一个问题一般使用/usr/bin/env命令来解决,但实际上将env命令作为Shebang使用时有一个很大的问题。


!/usr/bin/env stap-I tapset


编写这样的Shebang时,-I tapset就会变成env命令的选项,而不是SystemTap的选项。这时可以借用shell脚本的Shebang,一并解决这两个问题。这里以上一节的cursor.stp为例。


!/bin/sh

//usr/bin/env stap-I'dirname$0'/tapset- 0;exit$?

global x=20,y=20

probe input.move{

x+=rx;y+=ry

}

probe timer.ms(100){

if(x<=0)

x=1

else if(x>=41)

x=40

if(y<=0)

y=1

else if(y>=41)

y=40

ansi_clear_screen()

ansi_cursor_move(x, y)

print("@")

}


SystemTap将以//开头的行作为注释处理。而shell只是把//识别为根目录,因此可以在其后自由编写shell脚本。在这个示例中是使用dirname命令,使用(由$0传递的)可执行文件的相对路径指定Tapset。另外,将执行时传递给脚本的参数传递给SystemTap。通过这样的处理,可以向SystemTap脚本传递默认参数,同时自由添加SystemTap的参数。