linux下殺死進程(kill)的N種方法


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

ps -ef

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun15 ?        00:00:01 /sbin/init
root         2     0  0 Jun15 ?        00:00:00 [kthreadd]
root         3     2  0 Jun15 ?        00:00:00 [migration/0]
root         4     2  0 Jun15 ?        00:00:02 [ksoftirqd/0]
root         5     2  0 Jun15 ?        00:00:00 [stopper/0]
root         6     2  0 Jun15 ?        00:00:04 [watchdog/0]
root         7     2  0 Jun15 ?        00:00:00 [migration/1]
root         8     2  0 Jun15 ?        00:00:00 [stopper/1]
root         9     2  0 Jun15 ?        00:00:00 [ksoftirqd/1]
root        10     2  0 Jun15 ?        00:00:02 [watchdog/1]
……

或者:

ps -aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  19232  1504 ?        Ss   Jun15   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Jun15   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Jun15   0:00 [migration/0]
root         4  0.0  0.0      0     0 ?        S    Jun15   0:02 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S    Jun15   0:00 [stopper/0]
root         6  0.0  0.0      0     0 ?        S    Jun15   0:04 [watchdog/0]
root         7  0.0  0.0      0     0 ?        S    Jun15   0:00 [migration/1]
root         8  0.0  0.0      0     0 ?        S    Jun15   0:00 [stopper/1]
root         9  0.0  0.0      0     0 ?        S    Jun15   0:00 [ksoftirqd/1]
root        10  0.0  0.0      0     0 ?        S    Jun15   0:02 [watchdog/1]
……

此時如果我想殺了mysql的進程就在終端輸入:

kill -s 9 1827

其中-s 9 制定了傳遞給進程的信號是9,即強制、盡快終止進程。各個終止信號及其作用見附錄。

1827則是上面ps查到的mysql的PID。

簡單吧,但有個問題,進程少了則無所謂,進程多了,就會覺得痛苦了,無論是ps -ef 還是ps -aux,每次都要在一大串進程信息里面查找到要殺的進程,看的眼都花了。

進階篇:

改進1:

把ps的查詢結果通過管道給grep查找包含特定字符串的進程。管道符“|”用來隔開兩個命令,管道符左邊命令的輸出會作為管道符右邊命令的輸入。

ps -ef | grep mysql

root      6849 31342  0 18:19 pts/0    00:00:00 grep mysql
root     12373     1  0 Oct12 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql
mysql    12591 12373  2 Oct12 ?        14:44:30 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock

然后就是
kill -s 9 12591

改進2——使用pgrep:

一看到pgrep首先會想到什么?沒錯,grep!pgrep的p表明了這個命令是專門用於進程查詢的grep。

pgrep mysql

12591 

然后就是
kill -s 9 12591

改進3——使用pidof:

看到pidof想到啥?沒錯pid of xx,字面翻譯過來就是 xx的PID。

pidof mysql

12591 

和pgrep相比稍顯不足的是,pidof必須給出進程的全名。然后就是老生常談:

kill -s 9 12591

無論使用ps 然后慢慢查找進程PID 還是用grep查找包含相應字符串的進程,亦或者用pgrep直接查找包含相應字符串的進程pid,然后手動輸入給kill殺掉,都稍顯麻煩。有沒有更方便的方法?有!

改進4:

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

說明:

“grep mysql”的輸出結果是,所有含有關鍵字“mysql”的進程。

“grep -v grep”是在列出的進程中去除含有關鍵字“grep”的進程。

“cut -c 9-15”是截取輸入行的第9個字符到第15個字符,而這正好是進程號PID。

“xargs kill -s 9”中的xargs命令是用來把前面命令的輸出結果(PID)作為“kill -s 9”命令的參數,並執行該命令。“kill -s 9”會強行殺掉指定進程。

難道你不想抱怨點什么?沒錯太長了

改進5:

知道pgrep和pidof兩個命令,干嘛還要打那么長一串!

pgrep mysql | xargs kill -s 9

改進6:

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

kill: No such process

有一個比較郁悶的地方,進程已經正確找到並且終止了,但是執行完卻提示找不到進程。

其中awk '{print $2}' 的作用就是打印(print)出第二列的內容。根據常規篇,可以知道ps輸出的第二列正好是PID。就把進程相應的PID通過xargs傳遞給kill作參數,殺掉對應的進程。

改進7:

難道每次都要調用xargs把PID傳遞給kill?答案是否定的:

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

改進8:

沒錯,命令依然有點長,換成pgrep。

kill -s 9 `pgrep mysql`

改進9——pkill:

看到pkill想到了什么?沒錯pgrep和kill!pkill=pgrep+kill。

pkill -9 mysql

說明:"-9" 即發送的信號是9,pkill與kill在這點的差別是:pkill無須 “s”,終止信號等級直接跟在 “-“ 后面。之前我一直以為是 "-s 9",結果每次運行都無法終止進程。

改進10——killall:

killall和pkill是相似的,不過如果給出的進程名不完整,killall會報錯。pkill或者pgrep只要給出進程名的一部分就可以終止進程。

killall -9 mysql


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM