更優雅的 kill 進程

更優雅的 kill 進程

使用 unix 的時候常常需要 kill 一個進程,而我們又常常記不住進程的 pid,所有一般首先使用 ps 命令來打印系統中的進程,然後對 ps 得到的數據以進程名進行過濾,提取出相對應的 pid,以該 pid 爲參數調用 kill 就完成了整個的任務。

一個基礎的示例如下:

  1. 查找進程

    [longyu@debian:18:12:14] ~ $ ps -ef | grep bash
    longyu 7175 1964 0 18:05 pts/0 00:00:00 /bin/bash
    longyu 8313 7175 0 18:12 pts/0 00:00:00 grep --color=auto bash

  2. kill 進程

     kill -9 7175
    

-9 制定 kill 強制終止進程,這在某種情況下可能會造成問題,常常是進程所佔有的某些資源沒有正常釋放的問題。可以使用 kill 的默認發送信號,SIGTERM 來讓進程正常終止。

《APUE》 中對 SIGTERM 信號的講解內容如下:

這是 kill 命令在默認情況下發送的終止信號。因爲它可以被應用程序捕捉到,因此使用 SIGTERM 能夠給應用程序一個在 exit 之前執行回收工作優雅終止的機會(與 SIGKILL 正相反, SIGKILL 不能被捕捉到或忽略)。

一個可以判定爲存在問題的更高級的示例如下:

1. kill $(ps -ef | grep top | awk '/ top$/ {print $2}')
   bash: kill: (10793) - No such process

2. ps -ef | grep top | awk '/ top$/ {print $2}' | xargs kill

上面的第一個命令執行時,子 shell 創建的 grep 命令也將會被找到,子 shell 執行完後 grep 命令的主體進程已經終止,pid 已經無效,因此會有上面的錯誤。

第二個命令執行時,grep 命令的執行進程也會被找到,只是在發送 kill 信號的時候,該進程還沒有終止,因此不會報第一個命令中的錯誤。

一個改進的示例如下:

kill $(ps -ef | grep top | grep -v grep | awk '/ top$/ {print $2}')

上述命令能夠解決 grep 中找到子 shell 中 grep 命令主體進程的問題,但上述方式的執行效率較低。

一個更好的示例如下:

   ps -ef | awk '/ top$/ {print $2}' | xargs kill 
   
   kill $(ps -ef | awk '/ top$/ {print $2}')

使用 awk 來代替 grep,不僅沒有前幾個示例中存在的問題,也減少了進程的使用數目,減少了管道的使用數目,有很好的性能。

也可以使用 sed 來代替 awk,不過在這種方式下,sed 中的匹配字符串不容易寫出來,你需要使用匹配子串來完成,對於這個簡單的任務來講,你直接使用 awk 就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章