2011-07-01 43 views
53

我想在bash腳本中編寫一段代碼來檢查程序是否已經在運行。 條是否正在運行防止grep在輸入不匹配時返回錯誤

foo=`ps -ef | grep bar | grep -v grep` 

grep -v grep 

部分是確保「的grep條」不考慮PS爲了尋找我有以下結果

當bar沒有運行時,foo是空的。但我的問題在於腳本具有這樣的事實:

set -e 

這是一個標誌,在某些命令返回錯誤時終止腳本。 事實證明,當bar未運行時,「grep -v grep」與任何內容都不匹配,並且grep返回錯誤。我嘗試使用-q或-s但無濟於事。

有沒有解決方案? THX

回答

58

肯定的:

ps -ef | grep bar | { grep -v grep || true; } 

甚至:

ps -ef | grep bar | grep -v grep | cat 
+0

太好了!這解決了它。 Thx :) –

+6

第一個更好,因爲它也適用於「-o pipefail」,另一個好的快速設置,類似於「-e」。 –

+2

如果'grep'返回1表示沒有匹配,這會很好,但如果返回2(例如錯誤)會發生什麼? –

2
foo=`ps -ef | grep bar | grep -v grep` || true 
+0

x ||真的永遠是真的? – user48956

15

一個好的技巧,以避免grep -v grep是這樣的:

ps -ef | grep '[b]ar' 

這正則表達式只匹配字符串「酒吧」。但是,在ps輸出中,字符串「bar」不會與grep進程一起顯示。


在之前我瞭解pgrep,我寫了這個功能來自動執行上述命令的日子:

psg() { 
    local -a patterns=() 
    (($# == 0)) && set -- $USER 
    for arg do 
     patterns+=("-e" "[${arg:0:1}]${arg:1}") 
    done 
    ps -ef | grep "${patterns[@]}" 
} 

然後,

psg foo bar 

變成

ps -ef | grep -e '[f]oo' -e '[b]ar' 
+0

這是爲什麼? – grok12

+0

嘿,我已經完成了這個。它的工作原理是因爲表達式*匹配**欄**,但它*不匹配** b.ar ** – DigitalRoss

+5

@ grok12,在ps輸出中顯示的內容是'grep [b] ar', *正則表達式*'[b] ar'不能匹配*字符串*'[b] ar' - 正則表達式恰好匹配3個字符,而字符串包含5個字符 –

10

爲什麼要問ps提供大量的輸出與-ef如果你只是要扔掉99%的呢? ps,尤其是GNU版本是一款便捷功能的瑞士軍刀。試試這個:

ps -C bar -o pid= 1>/dev/null 

我在這裏指定-o pid=只是因爲,但實際上,因爲我們丟掉所有標準輸出的反正是沒有意義的。但是,如果您想知道實際運行的PID,這將會很有用。

ps如果-C未匹配任何內容,並且匹配爲零,將自動返回非零存在狀態。所以,你可以簡單地說,這

ps -C bar 1>/dev/null && echo bar running || echo bar not running 

或者

if ps -C bar 1>/dev/null ; then 
    echo bar running 
else 
    echo bar not running 
fi 

是不是很簡單?不需要grep,不需要兩次甚至一次。