本节书摘来自异步社区《UNIX编程环境》一书中的第5章,第5.6节,作者:【美】Brian W. Kernighan , Rob Pike著,更多章节内容可以访问云栖社区“异步社区”公众号查看
5.6 zap:使用名字终止进程
kill命令只能通过指定进程号来终止进程。要终止某个后台进程时,一般要运行ps命令以得到进程标识号,然后再把它作为kill的参数输入。通过一个命令程序打印一个参数,再把这个参数手工输入到另一个命令中,这个方法似乎有些笨拙。为什么不写一个程序,如zap,自动完成这些工作呢?
原因之一是终止进程是个危险的操作,执行时必须小心谨慎。一个保险的办法是交互地运行zap,用pick命令选择要终止的进程。
先简要回顾一下pick的功能:pick顺次打印它的每个参数,并请求用户响应,只有用户响应为y时才打印参数。(pick是下一节讨论的主题。)zap使用pick来确认那些通过名字选择的进程确实为用户所要终止的进程。
问题是,ps输出的是一些分隔开来的单词,pick将它们视作分离的参数处理,而不是一次处理一行。shell的标准处理是以空格为分割符分裂字符串的,如:
在该程序里,我们要控制shell对字符串的分裂,只用换行符分割两个相邻的“词”。
shell变量IFS(内部字段分隔符)是一个字符串,串中是那些用于在参数列表和for语句中分割词的字符。通常,IFS包括空格符、制表符和换行符,我们也可以把它改成任何有用的形式,如只有一个换行:
这里我们又使用了两个shell编程技巧:首先是通过一个可选参数来指定信号(注意如果不给出参数值,则SIG无定义,并作为null字符串处理);其次是用egrep代替grep,以便接受更复杂的模式,如’lsleep¦date’。echo语句用于打印ps输出的标题栏。
你也许会想到,为什么这个命令称为zap而不直接称为kill?主要原因是:与cal不同,我们实际上没有提供一个新的kill命令,zap需要交互地操作,此其一;我们还需要保留原来真正的kill程序,此其二。同时zap的执行速度较慢,所以附加程序的开销可想而知,其中ps(它是必须运行的)是开销最大的。我们将在下一章提供一个更有效的实现方法。
练习5-23 修改zap,使它由管道打印ps标题,而不必理会ps输出格式的改变。这将在多大程度上使程序复杂化?