1. 程式人生 > >更優雅的 kill 程序

更優雅的 kill 程序

更優雅的 kill 程序

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

一個基礎的示例如下:

  1. 查詢程序

    [[email protected]: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 就可以了。