2017-03-02 123 views
0

我有以下if語句來檢查服務,NewRelic的守護在這種情況下,正在運行...擊:如果語句總是成功

if [ $(ps -ef | grep -v grep | grep newrelic-daemon | wc -l) > 0 ]; then 
    echo "New Relic is already running." 

問題是,它總是返回爲真,即「New Relic已經在運行」。甚至當我單獨運行,如果條件雖然...

ps -ef | grep -v grep | grep newrelic-daemon | wc -l 

...返回0。我希望它在這裏什麼都不做返回的值= 0,但我的IF條件說> 0。

我可以在這裏看到什麼嗎?

+1

'> 0'正在寫一本名爲0的文件,不運行數值比較。 –

+2

順便說一句,對進程表進行grepping是一種代碼異味(表明你正在做某件你可能不應該做的事情,即比最佳實踐方法更不健壯)。如果你正在做過程監督,你可以問你的操作系統哪些服務正在運行 - 如果它是基於systemd的,那麼'如果systemctl是活動的newrelic-daemon';對於runit,'sv status newrelic-daemon'等。 –

回答

3

你正在嘗試做數字比較中[ ... ]>。這是行不通的;對值進行比較的號碼,使用-gt代替:如果出現可怕的錯誤

if [ "$(ps -ef | grep -v grep | grep -c newrelic-daemon)" -gt 0 ]; then 

的引號命令擴展防止語法錯誤(例如$PATH設置錯誤和外殼找不到grep)。由於您特意爲bash加了標記,因此您也可以僅使用[[ ... ]]而不是[ ... ]並且不帶引號。

作爲另一個特定於Bash的選項,您可以使用(( ... ))而不是任何一種方括號。這個版本的可能性更大,如果出現任何錯誤(如算術表達式語法真的希望所有參數爲數字)來生成一個語法錯誤,但它可以讓你使用更自然的比較操作:

if (("$(ps -ef | grep -v grep | grep -c newrelic-daemon)" > 0)); then 

在我使用grep -c而不是grep | wc -l;這樣我避免了一個額外的進程和一堆進程間I/O,因此wc可以計算grep已經枚舉的行數。

但是既然你只是檢查是否有任何匹配,你不需要做任何一個;最後grep將與真正的狀態退出,如果它發現任何東西,假的,如果沒有,那麼你可以這樣做:

if ps -ef | grep -v grep | grep -q newrelic-daemon; then 

(該-q保持grep從實際打印出匹配的行。)

另外,如果你正在尋找的進程名是字符串,而不是一個變量,我最喜歡這個任務的技巧是通過一個額外的grep -v grep修改,而不是管道該字符串是這樣,:

if ps -ef | grep -q 'newrelic[-]daemon'; then 

你可以選擇任何角色來放置方括號;重點是創建一個與目標進程名稱匹配的正則表達式模式,但不會與匹配模式本身,因此grep進程不會找到它自己的ps行。

最後,因爲你標記這個linux,請注意,大多數Linux發行版附帶的組合ps + grep命令調用pgrep,它可以實現這個要求,而你不必建立一個管道:

if pgrep newrelic-daemon >/dev/null; then 

(該的pgrep的MacOS/BSD版本接受-q選項像grep,這將讓你做無>/dev/null重定向,但我似乎已經在Linux系統中發現的版本不具有該選項。)

還有pidof;我還沒有遇到一個系統,有沒有pidofpgrep,但你應該遇到一個,你可以用同樣的方式:

if pidof newrelic-daemon >/dev/null; then 
+2

應該引用擴展。當然,'grep -c' *中的管道應該總是在stdout上發出一個整數,但是如果它不是(壞的'PATH'?),你不希望運行'[-gt 0]' ,當'[「」-gt 0]'會提供更有用的錯誤信息。 –

+0

謝謝,更新。 –

1

如果你想比較整數與test你必須使用-gt選項。請參閱:

man test 

man [ 
1

@Stephen:嘗試(改變[[[到你的代碼一起fi將完成如果塊完全):

if [[ $(ps -ef | grep -v grep | grep newrelic-daemon | wc -l) > 0 ]]; then 
    echo "New Relic is already running." 
fi 
+2

從技術上講,這可行,但我不會稱之爲好的做法 - 它運行的是字符串比較,而不是數字比較。與'0'比較沒什麼問題,但如果你正在運行'[[5> 10]]',結果會令人驚訝。 –

2

其他答案給了你更多的細節。我會做你正在嘗試用做:

if pidof newrelic-daemon >/dev/null; then 
    echo "New Relic is already running." 
fi 

甚至

pidof newrelic-daemon >/dev/null && echo "New Relic is already running." 
+2

如果一個人沒有'pidof',那麼也值得尋找'pgrep'。 –