1、interpreter file
#!/bin/sh
#!/bin/awk -f
...
注1:隐藏特定语言,写完脚本之后,直接执行即可
注2:效率的提高,如果直接用interpreter scripts执行
awk 'BEGIN {
for (i = 0; i < ARGC; i++)
printf "ARGV[%d] = %s\n", i, ARGV[i]
exit
}' $*
首先shell读取命令,试图用execlp文件名字,而shell
script是可执行文件,但不是machine executable,则返回
一个错误
然后,执行/bin/sh,附带该shell script的pathname作为
参数,这次shell正常运行脚本,但为了运行awk程序,shell
必须先后执行fork,exec和wait
另外,用shell script替代interpreter script带来额外的
开销
注3:interpreter scripts可以让我们的选择不只在/bin/sh
比如#!/bin/csh
2、system 函数
#include
int system(const char *cmdstring);
注1:system("data > file"); 等同于
time()-->localtime()-->strftime()
time() get the current calendar time
localtime() convert it to a broken-down time
strftime() format the result and write to file
注2:若cmdstring为NULL,只有系统支持该命令才会返回非0,可用
于测试该系统是否支持system函数
注3:system本身的事先是通过调用fork,exec和waitpid,所以
若fork错误或者waitpid返回不是EINTR的错误,system返回
-1,同时errno设置标明错误
若exec失败,说明shell不能执行,exit(127)
若fork,exec和waitpid都成功,返回shell的终止状态
注4:system统一了所有的错误处理和信号处理
注5:不要用system处理set-user-ID程序,会造成一个安全漏洞
因为这会通过fork和exec把权限传递过去
若想运行特殊权限并且生成另外一个进程,请直接使用fork和
exec,而在exec之前,fork之后,变回一般权限
3、Process Accouting
#include
/*
comp_t is a 16-bit "floating" point number with a 3-bit base 8 exponent and a 13-bit fraction. See linux/kernel/acct.c for the specific encoding system used.
*/
typedef u_int16_t comp_t;
struct acct
{
char ac_flag; /* Flags. */
u_int16_t ac_uid; /* Real user ID. */
u_int16_t ac_gid; /* Real group ID. */
u_int16_t ac_tty; /* Controlling terminal. */
u_int32_t ac_btime; /* Beginning time. */
comp_t ac_utime; /* User time. */
comp_t ac_stime; /* System time. */
comp_t ac_etime; /* Elapsed time. */
comp_t ac_mem; /* Average memory usage. */
comp_t ac_io; /* Chars transferred. */
comp_t ac_rw; /* Blocks read or written. */
comp_t ac_minflt; /* Minor pagefaults. */
comp_t ac_majflt; /* Major pagefaults. */
comp_t ac_swaps; /* Number of swaps. */
u_int32_t ac_exitcode; /* Process exitcode. */
char ac_comm[ACCT_COMM+1]; /* Command name. */
char ac_pad[10]; /* Padding bytes. */
};
/* Flags. */
enum
{
AFORK = 0x01,
/* Has executed fork, but no exec. */
ASU = 0x02,
/* Used super-user privileges. */
ACORE = 0x08, /* Dumped core. */
AXSIG = 0x10 /* Killed by a signal. */
};
注1:进程结束内核都会写一份记录,包括带命令名字的二进制数据,
使用的CPU时间,user ID和group ID,开始时间等等
注2:是否记录可以通过accton命令来进行控制
$accton 关掉Accouting
$accton $pathname 打开Accouting
注3:etime的时间并不完全等于sleep的时间,它还包括fork和
exit花费的时间,比如sleep(2),100clock ticks per
second,那么etime的值可能是202,肯定会比200大
4、User Identification
注1:找出运行程序的用户的登录名字,可以用
getpwuid(getuid());
但一个人可能在/etc/passwd里有多条记录,user ID一样,
但有不同的login name和login shell
所以上面的程序并不保险
#include
char *getlogin(void);
(Returns:pointer to string giving login name if OK,
NULL on error)
注2:如果程序是daemon,将会获取用户名失败,因为daemon并不跟
用户登录的终端相挂钩
5、Process Times
#include
clock_t times(struct tms *buf);
//填充struct tms
(Returns: elapsed wall clock time in clock ticks if OK, -1 on error)
struct tms {
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime;
/* user CPU time, terminated children */
clock_t tms_cstime;
/* system CPU time, terminated children */
}
注1:使用方法
struct tms tmsstart,tmsend;
clock_t start,end;
static long clktck = 0; //clock ticks per second
if ((start = times(&tmsstart)) == -1) // start
err_sys("times error");
...
// code need value time
...
if ((end = times(&tmsend)) == -1) // end
err_sys("times error");
if ((clktck = sysconf(_SC_CLK_TCK)) < 0)
// fetch clock ticks per second
err_sys("sysconf error");
printf(" real: %7.2f\n",(end - start)/(double)clktck
);
printf(" user: %7.2f\n",
(tmsend->tms_utime - tmsstart->tms_utime) / (double
)clktck);
printf(" sys: %7.2f\n",
(tmsend->tms_stime - tmsstart->tms_stime) / (double
)clktck);
printf(" child user: %7.2f\n",
(tmsend->tms_cutime - tmsstart->tms_cutime) / (double)clktck);
printf(" child sys: %7.2f\n",
(tmsend->tms_cstime - tmsstart->tms_cstime) / (double)clktck);
阅读(831) | 评论(0) | 转发(0) |