shell脚本学习指南[五](Arnold Robbins & Nelson H.F. Beebe著)

2019-09-23 09:42:00王振洲

    EGREP_OPTIONS= egrep "$EGREPFLAGS" |
        sort -b -k1,1 -k2,2 | uniq -c |
            sort -b -k2,2 -k1nr,1 -k3,3 |
                awk '{
                    user = (LAST == $2)?" " : $2
                    LAST = $2
                    printf("%-15st%2dt%sn",user,$1,$3)
                }'

内容都很简单,不再赘述注释。

进程列表有了,如何控制或者删除某一个进程呢。之前有说exit()能让进程终止,但有时候我们会提前终止,这时我们需要kill命令。kill命令会传送信号(signal)给指定的执行程序,不过它有两个例外,稍后提到。进程接到信号,并处理之,有时可能直接选择忽略它们。只有进程拥有者或root、内核、进程本身可以传送信号给它。但是接收信号的进程本身无法判断信号从何而来。不同的系统支持不同的信号类型,你可以通过kill -l 来列出你当前使用的系统支持的信号类型。每个处理信号的程序都可以自由决定如何解决接到的这些信号。信号名称反应的是惯用性(conventions),而非必须性(requirement),所以对不同的程序而言,信号所表示的意义也会稍有不同。

kill pid 就可以直接终止进程。控制进程的话,就使用刚才kill -l罗列出来的进程信号,用法:kill[-ssignal|-p][-a]pid... 需要自行了解自己系统的进程信号。比如:


$ kill -STOP 17787 #终止进程
$ sleep 36000 && kill -CONT 17787 & #十小时后恢复

删除进程必须直到四个信号:ABRT(中断)、HUP(搁置)、KILL、TERM(终结)。不同系统有所不同貌似,可以查看一下,名字应该类似:
kill -l | grep -e "KILL|BRT|HUP|TERM"

有些程序会在结束前做些清理工作,一般TERM信号解释为“快速清理并结束”,如果未指定信号,默认的kill会传送此信号。ABRT类似TERM它会抑制清除操作,并产生进程内的影像的副本。HUP类似要求中止,时常表示进程应该先停止正在处理的事情,然后准备处理新工作。有两个进程没有任何进程可以忽略的:KILL和STOP,这两个信号一定会立刻被传送,但是也有特例情况,根据实际情况也可能会被延时的。不同系统平台有差异。

小心使用这些终止命令。当程序非正常中止,都可能在文件系统留下残余数据,这些残余数据除了浪费空间,还可能导致下次执行程序发生问题。比如:daemon、邮件客户端程序、文字编辑器、以及网页浏览器都会产生锁定(lock)。如果程序第二实例被启动,而第一实例仍在执行时,第二个实例会侦测到已存在的lock,回报该事实并立即中止。最糟糕的是,这些程序很少会告诉你lock文件的文件名,并很少将它写入文件里。如果该lock文件长期执行进程的残余数据,你可能发现程序无法执行,直到你找到lock并删除为止。