首先,你應該使用一個while read
結構,而不是for
。使用for
循環,必須等待$(...)
中的命令才能在for循環啓動之前執行。另外,你可能會溢出命令緩衝區。不是今天的一個主要問題,但是當你進入它,你將永遠不會得到任何跡象表明發生了錯誤:
ps | awk '$4 == "foo" { print $1 }' | while read pid
do
i=1
echo "killing foo at pid $pid"
kill $pid && echo 'ok' || echo 'failed'
done
沒什麼跟你的問題,但我需要的是在我胸口。
現在到您的答案:
的awk
自動完成一個循環,這樣以來你使用awk
無論如何,爲什麼不讓它爲你做的工作?大多數awk
實現都有system
命令,因此您可以在awk
腳本中執行kill
。
另外,看看man ps
並檢查您的PS選項。大多數ps命令採用-o
選項,該選項允許您指定要打印的字段。我的ps
命令(恰好在OS X上)允許您使用ucomm
,它只是沒有目錄或命令行參數的命令的名稱。聽起來對你的情況有用。我將使用ps -opid, ucomm
這將只打印兩列的ps
命令:PID,和命令名SANS目錄和命令行參數:
$ ps -o pid,ucomm
PID UCOMM
1 launchd
10 kextd
11 UserEventAgent
12 mDNSResponder
13 opendirectoryd
14 notifyd
15 fseventsd
16 configd
17 diskarbitrationd
18 syslogd
(只是一個警告,它看起來像ucomm
削減掉的東西在第14或第16列,只是爲了讓你知道)。
對於awk
,我們可以使用-v
參數定義一個Awk變量。如果您編寫shell腳本,並且希望awk從命令參數中獲取程序的名稱,這很有用。
在awk中,如你所知,$ 1將代表PID和$ 2將代表命令SAN的目錄或命令行參數。
我們可以使用$2 == command
來篩選出您的ps
命令中的所有行,其中命令爲foo
。這是if
聲明的快捷方式。
而且,大多數awk
的實現都有system
函數,可用於從awk
腳本中運行諸如kill
之類的命令。看起來我們有幾乎所有我們需要的一切:
ps -o pid,ucomm | awk -v command="foo" '$2 == command {system("kill " $1)}'
這是一個乾淨的一個套,但它並不檢查系統命令的狀態,也不會迴應了,當它出現故障或有什麼命令和PID你正在殺害。
Awk不只是一個深奧的命令的好事。這也是一種深奧的編程語言。我們可以測試system
命令的返回並添加一些打印語句。我沒有測試這一點,但它應該是相當接近:
ps -o pid,ucomm | awk -v command="foo" '$2 == command {
print "Killing " $2 " at PID " $1
if (system("kill " $1)) {
print "Failed to kill PID " $1
}
}'
的if
可能必須if (! system("kill " $1)) {
代替。
謝謝!我精神振奮:) – user46874 2012-02-24 03:32:31