1.案例現(xiàn)象
一般來(lái)講,我們?cè)?kill 掉一個(gè)進(jìn)程的時(shí)候通常有兩個(gè)選擇:
- 找到進(jìn)程的 pid 號(hào),然后執(zhí)行 kill 命令
- 找到進(jìn)程的名字,然后執(zhí)行 pkill 命令
pkill 和 kill 命令都是向指定的進(jìn)程發(fā)送信號(hào),從而完成終結(jié)進(jìn)程的操作,主要區(qū)別在于 pkill 命令與 pgrep 配套使用,能夠踢出指定終端用戶、同時(shí)根據(jù) UID 和用戶名來(lái)終止進(jìn)程
今天給大家分享一件我在使用 pkill 命令時(shí)遇到的比較有意思的事情
這臺(tái)機(jī)器上(Cent OS7)運(yùn)行著一個(gè)進(jìn)程 after_sleep60s_output
[root@localhost ~]# ps -ef | grep [a]fter
root 49146 48933 0 09:39 pts/0 00:00:00 /usr/local/bin/after_sleep60s_output
執(zhí)行 pkill 命令
[root@localhost ~]# pkill after_sleep60s_output
然后當(dāng)我使用 ps 命令查看的時(shí)候,我發(fā)現(xiàn)這個(gè)進(jìn)程還在,而且返回了狀態(tài)碼 1
[root@localhost ~]# echo $?
1
用 kill 命令試試,發(fā)現(xiàn)成功了
[root@localhost ~]# kill 49146
奇怪?為什么用 pkill 命令 kill 不掉這個(gè)進(jìn)程?
2.定位問(wèn)題
通過(guò) man pkill
我發(fā)現(xiàn),pkill 命令是默認(rèn)結(jié)合 pgrep 來(lái)使用的
pgrep 首先找出目標(biāo)進(jìn)程(running),然后 pkill 再根據(jù) pgrep 的結(jié)果來(lái) kill 目標(biāo)進(jìn)程
pgrep looks through the currently running processes and lists the process IDs which match the selection criteria to stdout. All the criteria have to match. For example,
? $ pgrep -u root sshd
will only list the processes called sshd AND owned by root. On the other hand,
? $ pgrep -u root,daemon
will list the processes owned by root OR daemon.
pkill will send the specified signal (by default SIGTERM) to each process instead of listing them on stdout.
pgrep 找目標(biāo)進(jìn)程是通過(guò)獲取 /proc/[pid]/stat
文件中的進(jìn)程名來(lái)實(shí)現(xiàn)的,但是這個(gè)文件中的進(jìn)程名是有長(zhǎng)度限制的——只有15個(gè)字符
Linux 中的每一個(gè)進(jìn)程都維護(hù)了一個(gè) struct_task_struct
結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體在/usr/src/kernels/內(nèi)核版本/include/linux/sched.h
里面
這里面有一個(gè)字段定義了不包括路徑的可執(zhí)行文件的名字,最大長(zhǎng)度是 16 bytes,除去最后一個(gè)留給 null 的,就只有最多 15 個(gè)字符
/* Task command name length */
#define TASK_COMM_LEN 16
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
- initialized normally by setup_new_exec */
然后我們看一下上面例子中進(jìn)程對(duì)應(yīng)的 stat 文件
[root@localhost ~]# cat /proc/49146/stat
49212 (after_sleep60s_) S 48933 49212 48933 3 .....
可以看到文件里面的進(jìn)程名字被截?cái)喑闪?5個(gè)字符:after_sleep60s_
如果要使用 pkill 命令,正確方式如下:
[root@localhost ~]# pkill after_sleep60s_
你也可以加一個(gè) -f
參數(shù)
[root@localhost ~]# pkill -f after_sleep60s_output
這個(gè)參數(shù)會(huì)告訴 pkill 不去/proc/[pid]/stat
文件找進(jìn)程,而是去 /proc/[pid]/cmdline
里面找
這個(gè)文件里面包含了進(jìn)程啟動(dòng)的時(shí)候的完整命令,包括參數(shù)
[root@localhost ~]# /proc/49146/cmdline
/usr/local/nginx/sbin/after_sleep60s_output
3.解決問(wèn)題
想要準(zhǔn)確的 kill 掉一個(gè)進(jìn)程,可以使用下面的方法:
-
pidof
命令獲取到進(jìn)程對(duì)應(yīng)的 PID,再使用kill
命令 - 使用 systemd 啟動(dòng)的,通過(guò)
systemctl
命令來(lái)控制 - 使用 pkill 命令的時(shí)候建議加上
-f
參數(shù)
最后附上相關(guān) issue 鏈接:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-409493.html
1、https://stackoverflow.com/questions/23534263/what-is-the-maximum-allowed-limit-on-the-length-of-a-process-name文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-409493.html
到了這里,關(guān)于kill 進(jìn)程時(shí)遇到的一件有意思的事情的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!