2014-11-13 33 views
1

我試圖採取ps axo uname,pid,etime,time,cmd的輸出,並殺死所有相關流程與ETIME> = 10如果他們的etime大於X的時間量,我該如何殺死特定的進程?

我需要殺死的PID僅適用於被存儲在一個單獨的文件中的特定用戶,users.txt

基本上,我想查看我所有的列,並且想要查找屬於特定用戶的所有php {5,54}進程,並存儲在一個文件中,並在執行時間超過10分鐘時終止這些進程。 (殺-9不需要)

例PS輸出:

username 574  01:37 00:00:18 /ramdisk/bin/php54 /home/username/public_html/index.php 
usernum2 1367  10:28 00:00:16 /ramdisk/bin/php54 /home/usernum2/public_html/index.php 
user3  3971 1-04:17:31 00:00:14 /ramdisk/bin/php54 /home/user3/public_html/index.php 
usernum4 9130  14:05:32 00:00:29 /ramdisk/bin/php54 /home/usernum4/public_html/index.php 
username 9189 1-01:31:12 00:00:25 /ramdisk/bin/php54 /home/username/public_html/index.php 

我的想法一直把ps輸出到一個文件(說procs.txt),然後通過一些grep。 EG:

ps axo uname,pid,etim,time,cmd | grep 'php5' | tee procs.txt

我可以有兩條獨立的線路:一個是說,如果第3列是超過5個字符殺了PID,這是很容易,然後又用類似下面的,但沒有按「留下我與相關的PID,所以我不能殺了他們:

for i in $(cat users.txt); do grep $i procs.txt | awk '{print $3}' | awk -F: '{print $(NF-1)}' | awk '$1>=10{print $1}'; done

+0

[這個答案](http://serverfault.com/a/181503)可能是你想要的。 – chrisaycock

+0

我在之前的搜索中看到了這一點。它假設一個靜態值(在他們的例子中是「page.py」),但是我的變化並且需要重新格式化。 EG:1:04:17:31 vs 10:28。感謝您的回覆。 – Mic

+0

對於Fedora上的這個問題的任何人,他們可以使用ps和etimes(秒),這使得更容易,如果> = ...不幸的是我在CentOS上,不能安裝procps-ng – Mic

回答

1

以下是bash的解決方案。

要查找一個文件匹配php5php54,對於用戶來說,所有的過程,我會用U選項psegrep

ps xo uname,pid,etim,time,cmd U"$(echo $(< users.txt))" | egrep '/php54? ' 

U選項將只顯示屬於進程提供的用戶列表。 <cat的shell內置程序,並且使用echo可將文件條目整合到ps命令期望的單個行中。

'/php54? '指示4是可選的,最後的空格確保它不匹配(例如)php52egrep使用正則表達式,因此它允許使用元字符?

此命令的輸出然後可以通過管線處理線與while read

ps xo uname,pid,etim,time,cmd U"$(echo $(< users.txt))" | egrep '/php54? ' \ 
| while read a 
    do cols=($a) 
    elapsed=${cols[2]} 
    if [ ${#elapsed} -gt 5 ] 
    then kill ${cols[1]} 
    elif [ ${elapsed%%:*} -gt 9 ] 
    then kill ${cols[1]} 
    fi 
    done 

cols得到的數組指派,分割線a上空白的邊界。 USER位於cols[0],PID爲cols[1],ELAPSED位於cols[2]。如果ELAPSED的字符串長度大於5(表示經過時間至少一個小時),或者如果分鐘字段大於9(經過的時間至少10分鐘),PID將被終止。 %%擴展運算符會執行最長匹配後綴刪除。

該解決方案可以通過read直接-ing進入相關領域進行壓縮:

ps xo uname,pid,etim,time,cmd U"$(echo $(< users.txt))" | egrep '/php54? ' \ 
| while read user pid elapsed rest_of_line 
    do if [ ${#elapsed} -gt 5 ] 
    then kill $pid 
    elif [ ${elapsed%%:*} -gt 9 ] 
    then kill $pid 
    fi 
    done 
+0

如果你有一個用戶文件用換行符,你可以使用這種方式,'echo'的方式在我的系統上不起作用:'「$(

+0

我現在看到它有一個輕微的錯字'etim'而不是'etime',如果你改變它現在對我有用 - 我以前沒有注意到它,而且我輸入了我自己的命令。 –

+0

輝煌燦爛!這是完美的。非常感謝你:)(而且,如果不知道它,你的回答就會變得更加簡單,就像......聖誕節一樣!) – Mic