尚观第七天学习后总结pgrep与kill的使用

来源:互联网 发布:网络直播 yy 编辑:程序博客网 时间:2024/04/30 04:49

想结束系统中指定的进程,有以下指令可能参考:

ps -ef | grep pure-ftpd | grep -v grep | awk '{print $2" "$3}' | xargs kill -9 = pkill pure-ftpd

killall -9 nginx 或者 kill -9 `ps aux |grep -i nginx |grep -v grep |awk '{print $2}'` = kill -9 `pgrep nginx`

以上是很常规的方法,下面我们介绍一种系统自带的工具的用法。

名称
pgrep, pkill(其实是pgrep的链接) – 查找或者发信号给进程通过名称和其它属性,我们能得到进程许多信息和通过这些来对其进行相关操作。

语法
pgrep [-flvx] [-n | -o] [-d delim] [-P ppidlist] [-g pgrplist] [-s sidlist] [-u euidlist] [-U uidlist] [-G gidlist] [-t termlist] [-c ctidlist] [-z zoneidlist] [pattern]

pkill [-signal] [-fvx] [-n | -o] [-P ppidlist] [-g pgrplist] [-s sidlist] [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist] [-t termlist] [-T taskidlist] [-c ctidlist] [-z zoneidlist] [pattern]

说明
  pgrep程序检查在系统的中活动进程,报告进程属性匹配命令行上指定条件的进程的ID。每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行。对于每个属性选项,用户可以在命令行上指定一个以逗号分割的可能值的集合。

例如:
  pgrep -G other,daemon
  匹配真实组ID是other或者是daemon的进程。如果多个条件被指派,这些匹配条件按逻辑与"AND"规则运算。

例如:
  pgrep -G other,daemon -U root,daemon
  匹配进程它的属性是:
  (真实的组ID是other或者是daemon) 与 (真实的用户ID是root或者是daemon)。

  pkill函数和pgrep相同,除了匹配的进程被信号通知就像用kill(1)替代了pgrep的进程ID的输出,一个信号名称或者数字可以作为pkill的第一个命令行选项。

选项
  支持下面的选项:
  -c ctidlist  仅匹配列表中列出的ID的进程数。
# pgrep -c ssh -l
6

  -d delim  指定每一个匹配的进程ID之间分割字符串,如果没有 -d 选项指定,默认的是新行字符,-d 选项仅在pgrep命令中有效。

  -f 正则表达式模式将执行与完全进程参数字符串 (从/proc/nnnnn/psinfo文件的pr_psargs字段获得)匹配。如果没有 -f 选项,表达式仅对执行文件名称(从/proc/nnnnn/psinfo文件pr_fname字段获得)匹配。
# pgrep -f ng -l
2159 nginx: master process /usr/sbin/nginx
2160 nginx: worker process
2222 hald-addon-input: Listening on /dev/input/event3 /dev/input/event2 /dev/input/event0
2230 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
2231 hald-addon-storage: polling /dev/hdc (every 2 sec)

  -g pgrplist 仅匹配进程组ID在给定列表中的进程,如果组0包括在列表中,这个被解释为pgrep或者pkill进程的组ID。
# pgrep -g 2159 -l
2159 nginx(所有nginx进程的父进程)
2160 nginx

  -G gidlist 仅匹配真实组ID在给定列表中的进程,每一个组ID可以使用组名称或者数字的组ID指定。
# pgrep -G 1000 -l
2388 sshd
2395 bash
2420 sshd
2421 sftp-server

  -l 长格式输出,输出每一个匹配进程的名称连同进程ID,进程名称从pr_psargs 或者 pr_fname字段获得,依赖于-f选项是否指定。-l选项仅在pgrep命令中有效。

  -n 匹配最新(最近生成的)符合所有其它匹配条件的进程,不能和-o选项一起使用。

  -o 匹配最旧(最早生成的)符合所有其它匹配条件的进程,不能和-n选项一起使用。

  -P ppidlist 仅匹配给定列表中父进程ID的进程。
# pgrep -P 2159 -l
2160 nginx

  -s sidlist 仅匹配进程会话ID在给定列表中的进程,如果ID 0在列表中,这个解释为pgrep或者pikill进程的会话ID。
# pgrep -s 2159 -l
2159 nginx
2160 nginx

  -t termlist 仅匹配与给定列表中终端关联的进程,每一个终端指定为在/dev中终端设备路径名称的后缀。例如term/a 或者 pts/0。
# pgrep -t pts/1 -l
2395 bash

  -u euidlist 仅匹配有效用户ID在给定列表中的进程,每个用户ID可以通过一个登录名称或者数字的用户ID指定。
# pgrep -u hto -l
2388 sshd
2395 bash

  -U uidlist 仅匹配真实的用户ID在给定列表中的进程,每个用户ID可以通过一个登录名称或者数字的用户ID指定。
# pgrep -U hto -l
2388 sshd
2395 bash
2420 sshd
2421 sftp-server

  -v 反向匹配。匹配所有的进程除了符合匹配条件的。

  -x 仅认为进程的参数字符串或者执行文件名称正确匹配规定模式是匹配的进程,模式被认为是准确的当所有在进程参数字符串或者可执行文件名称的字符匹配模式。
# pgrep -d, -x nginx
2159,2160

  -z zoneidlist 仅匹配区域ID在给定列表中的进程,每一个区域ID可以使用一个区域名称或者一个数字的区域ID指定,这个选项仅在全局区域中执行有效,如果pkill程序用来往其它区域的进程发信号,进城必须宣称{PRIV_PROC_ZONE}特权。

  -signal 指定发往每一个匹配进程的信号。如果没有指定,SIGTERM 是默认的信号。-signal仅在pkill命令中作为第一个选项有效。信号可以是在signal.h中定义的没有SIG前缀的一个符号名字,也可是一个相应的信号数值。

操作

支持如下操作:
pattern
  指定一个扩展正则表达式(Extended Regular Expression (ERE))模式来匹配可执行文件名称或者完整的进程参数字符串。ERE语法的完整描述参看regex(5)。

示例

例1 获得一个进程的ID号
获得nginx的进程ID:
$ pgrep -x -u root nginx
2123

例2 终止一个进程
终止最近生成的apache2:
$ pkill -n apache2

Example 3: Find the process ID of the named daemon:
$ pgrep -u root named

Example 4: Make syslog reread its configuration file:
$ pkill -HUP syslogd

Example 5: Give detailed information on all xterm processes:
$ ps -fp $(pgrep -d, -x xterm)

Exit Status
  如下退出值被返回:
  0 一个或者多个进程被匹配。
  1 没有进程被匹配。
  2 指定了无效的命令行参数。
  3 出现一个致命的错误。


常规篇:

首先,用ps查看进程,方法如下:

$ ps -ef

……

smx      1822     1  0 11:38 ?        00:00:49gnome-terminal

smx      1823  1822  0 11:38 ?        00:00:00gnome-pty-helper

smx      1824  1822  0 11:38 pts/0    00:00:02 bash

smx      1827     1  4 11:38 ?        00:26:28/usr/lib/firefox-3.6.18/firefox-bin

smx      1857  1822  0 11:38 pts/1    00:00:00 bash

smx      1880  1619  0 11:38 ?        00:00:00update-notifier

……

smx      11946 1824  0 21:41 pts/0    00:00:00 ps -ef

或者:

$ ps -aux

……

smx      1822  0.1  0.8  58484 18152 ?       Sl   11:38   0:49 gnome-terminal

smx      1823  0.0  0.0   1988   712 ?       S    11:38   0:00 gnome-pty-helper

smx      1824  0.0  0.1   6820  3776 pts/0    Ss  11:38   0:02 bash

smx      1827  4.3  5.8 398196 119568 ?       Sl  11:38  26:13 /usr/lib/firefox-3.6.18/firefox-bin

smx      1857  0.0  0.1   6688  3644 pts/1    Ss  11:38   0:00 bash

smx      1880  0.0  0.6  41536 12620 ?       S    11:38   0:00 update-notifier

……

smx     11953  0.0  0.0   2716  1064 pts/0    R+  21:42   0:00 ps -aux

 

此时如果我想杀了火狐的进程就在终端输入:

$ kill -s 9 1827

其中-s 9制定了传递给进程的信号是9,即强制、尽快终止进程。各个终止信号及其作用见附录。

 

进阶篇:

 

改进1:

ps的查询结果通过管道给grep查找包含特定字符串的进程。管道符“|”用来隔开两个命令,管道符左边命令的输出会作为管道符右边命令的输入。

$ ps -ef | grepfirefox

smx      1827     1  4 11:38 ?        00:27:33/usr/lib/firefox-3.6.18/firefox-bin

smx     12029  1824  0 21:54 pts/0    00:00:00 grep--color=auto firefox

这次就清爽了。然后就是

$kill -s 9 1827

 

改进2——使用pgrep

一看到pgrep首先会想到什么?没错,greppgrepp表明了这个命令是专门用于进程查询的grep

$ pgrep firefox

1827

看到了什么?没错火狐的PID,接下来又要打字了:

$kill -s 9 1827

 

改进3——使用pidof

看到pidof想到啥?没错pid of xx,字面翻译过来就是 xxPID

$ pidof firefox-bin

1827

pgrep相比稍显不足的是,pidof必须给出进程的全名。然后就是老生常谈:

$kill -s 9 1827

无论使用ps然后慢慢查找进程PID还是用grep查找包含相应字符串的进程,亦或者用pgrep直接查找包含相应字符串的进程PID,然后手动输入给kill杀掉,都稍显麻烦。有没有更方便的方法?有!

 

改进4:

$ps -ef | grepfirefox | grep -v grep | cut -c 9-15 | xargs kill -s 9

说明:

“grep firefox”的输出结果是,所有含有关键字“firefox”的进程。

“grep -v grep”是在列出的进程中去除含有关键字“grep”的进程。

“cut -c 9-15”是截取输入行的第9个字符到第15个字符,而这正好是进程号PID

“xargs kill -s 9”中的xargs命令是用来把前面命令的输出结果(PID)作为“kill -s 9”命令的参数,并执行该命令。“kill -s 9”会强行杀掉指定进程。

难道你不想抱怨点什么?没错太长了

 

改进5:

知道pgreppidof两个命令,干嘛还要打那么长一串!

$ pgrep firefox |xargs kill -s 9

 

改进6:

$ ps -ef | grepfirefox | awk '{print $2}' | xargs kill -9

kill: No suchprocess

有一个比较郁闷的地方,进程已经正确找到并且终止了,但是执行完却提示找不到进程。

其中awk '{print $2}'的作用就是打印(print)出第二列的内容。根据常规篇,可以知道ps输出的第二列正好是PID。就把进程相应的PID通过xargs传递给kill作参数,杀掉对应的进程。

 

改进7:

难道每次都要调用xargsPID传递给kill?答案是否定的:

$kill -s 9 `ps -aux| grep firefox | awk '{print $2}'`

 

改进8:

没错,命令依然有点长,换成pgrep

$kill -s 9 `pgrepfirefox`

 

改进9——pkill

看到pkill想到了什么?没错pgrepkillpkillpgrep+kill

$pkill - firefox

说明:"-9"即发送的信号是9pkillkill在这点的差别是:pkill无须,终止信号等级直接跟在 “-“后面。之前我一直以为是 "-s 9",结果每次运行都无法终止进程。

 

改进10——killall

killallpkill是相似的,不过如果给出的进程名不完整,killall会报错。pkill或者pgrep只要给出进程名的一部分就可以终止进程。

$killall -9 firefox

 

 

附录:各种信号及其用途

Signal DescriptionSignal number on Linux x86[1] 

SIGABRT Processaborted 6 

SIGALRM Signalraised by alarm 14 

SIGBUS Bus error:"access to undefined portion of memory object" 7 

SIGCHLD Childprocess terminated, stopped (or continued*) 17 

SIGCONT Continue ifstopped 18 

SIGFPE Floatingpoint exception: "erroneous arithmetic operation" 8 

SIGHUP Hangup1 

SIGILL Illegalinstruction 4 

SIGINT Interrupt2 

SIGKILL Kill(terminate immediately) 9 

SIGPIPE Write topipe with no one reading 13 

SIGQUIT Quit anddump core 3 

SIGSEGVSegmentation violation 11 

SIGSTOP Stopexecuting temporarily 19 

SIGTERM Termination(request to terminate) 15 

SIGTSTP Terminalstop signal 20 

SIGTTIN Backgroundprocess attempting to read from tty ("in") 21 

SIGTTOU Backgroundprocess attempting to write to tty ("out") 22 

SIGUSR1User-defined 1 10 

SIGUSR2User-defined 2 12 

SIGPOLL Pollableevent 29 

SIGPROF Profilingtimer expired 27 

SIGSYS Bad syscall31 

SIGTRAPTrace/breakpoint trap 5 

SIGURG Urgent dataavailable on socket 23 

SIGVTALRM Signalraised by timer counting virtual time: "virtual timer expired"26 

SIGXCPU CPU timelimit exceeded 24 

SIGXFSZ File sizelimit exceeded 25

 



原创粉丝点击