2009-11-11 88 views
7

這個腳本總是返回「running」,這是否有任何理由,無論我的進程是啓動還是停止?if語句總是計算爲TRUE

if ps ax | grep -v grep | grep "processName" > /dev/null 
then 
    echo $"running" 
else 
    echo $"not running" 
fi 

非常感謝您

UPDATE: 添加我的劇本的一個完整的例子,也許還有其他地方的一些錯誤。

case "$1" in 
    start) 
    # Start daemons. 

    echo -n $"Starting daemon: " 
    ;; 

    stop) 
    # Stop daemons. 
    echo -n $"Shutting down: " 
    echo 
    ;; 
    status) 
    pgrep -f "ProcessName" > /dev/null 
    if [ $? -eq 0 ]; then 
     echo $"ProcessName is running" 
    else 
     echo $"ProcessName is not running" 
    fi 
    ;; 
    restart) 
    $0 stop 
    $0 start 
    ;; 

    *) 
    echo $"Usage: $0 {start|stop|status|restart}" 
    exit 1 
esac 

更新2:

[[email protected] init.d]# pgrep -f "MyProcess" > /dev/null 
[[email protected] init.d]# echo $? 
0 
[[email protected] init.d]# service MyProcess stop 
Shutting down MyProcess: Terminated 
[[email protected] init.d]# pgrep -f "MyProcess" > /dev/null 
[[email protected] init.d]# echo $? 
1 

if [ $? -eq 0 ]; then似乎是真實的

+3

要回答你的問題,是的。 ;-) – 2009-11-11 14:05:37

+0

@Mike,當你將輸出重定向移除到/ dev/null時,你會看到什麼?事實上,你的流程或其他類似的名稱正在運行嗎? – pilcrow 2009-11-11 14:44:59

+0

@pilcrow,當我的過程開始時,我看到了過程的結果,當過程停止時,我看不到任何結果。 – Mike 2009-11-11 14:53:16

回答

16

試試這個:

ps aux | grep -q "[p]rocessName" 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

周圍的processName手段的第一個字母的支架就不需要「 grep -v grep「,而-q表示我們不需要管道到/ dev/null

$?給你前面執行的命令的返回碼。因此,測試它是否爲0會指示「grep」是否找到了它所要查找的內容。

更新

如果你的進程名是非常短的(比如「杯」),你可能會得到誤報,因爲它可能太匹配其他進程(說「的cupsd」)。你可以通過grep匹配整個單詞來解決這個問題 - 添加「-w」標誌。

不是說這種技術不完美。您可能會在用戶名/日期字段中輸入匹配的條目。如果發生這種情況,請查閱「man ps」,並在做grep之前更好地選擇打印出來的內容。或者,使用awk預先篩選輸出以僅提取顯示進程/ cmd名稱的列。 E.g:

ps aux | awk '{print $11}' | grep -q -w "[p]rocessName" 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

更新2

你也可以使用p纖ep如下回答提示。

對於非常短的進程名,你可能想要指定單詞邊界(\ b)在和你的進程名之後,以防止過匹配(如上所述)

pgrep "\bprocname\b" > /dev/null 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

更新3

從更新的問題中,我看到你正在從一個init腳本運行它。 pgrep總會有與腳本本身相匹配的危險。請嘗試:

pgrep Processname | grep -q -v $$ 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

從pgrep匹配中排除腳本的PID。

更新4

(最後更新?手指交叉)

如果init腳本通過「服務」命令來運行,那麼我們需要過濾掉父PID爲好。如何:

pgrep Processname | grep -v $$ | grep -q -v $PPID 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 
+4

嘿,這實際上是一個用[p] rocessname - +1來證明老狗的漂亮技巧,可以學習新的技巧。 – paxdiablo 2009-11-11 14:16:29

+0

當我嘗試時,它一直在運行。 – Mike 2009-11-11 14:16:39

+0

他應該能夠'如果ps aux | grep -q「[p] rocessName」;然後回聲跑步;否則回聲不運行; fi'額外的測試使用[是不必要的。 – 2009-11-11 14:19:09

-1

你不是做測試的所有時光。在方括號內的測試條件,像這樣:

如果[條件您的測試]

+1

沒有[],if會測試給出命令的退出狀態,所以他的腳本(正確的精神)試圖測試grep的退出。 – 2009-11-11 14:17:57

+0

@Emil是有效的不測試他想要的狀態!實際上,如果anyAccessibleCommand不帶括號,則返回true – ennuikiller 2009-11-11 14:20:02

+1

嘗試'if/bin/false;那麼echo ennuikiller是正確的; fi' – mob 2009-11-11 14:44:40

2

可能是因爲grep "processName"發現自己。我昨天發現這種自我同樣的問題,但我xarg荷蘭國際集團的結果kill ...

作爲替代,你可能想嘗試的pgrep命令,而不是你的ps串和各種grep S:

[email protected]:~$ pgrep bash 
415 
3477 
[email protected]:~$ echo $? 
0 
[email protected]:~$ pgrep arf 
[email protected]:~$ echo $? 
1 
+0

+1的提醒p纖ep :) – 2009-11-11 14:36:03

+0

@Stephen的,不,OP排除包含「grep的」在他原來的管道中間PS線條。 – pilcrow 2009-11-11 14:43:28

+0

是的,pgrep非常靈活。 – 2009-11-11 15:06:06

1

天兒真好,

順便說一句,而不是

ps ax | grep -v grep | grep "processName" 

嘗試做

ps ax | grep "[p]rocessName" 

PS時,列出grep的功能,因爲它是看到其中被你的grep字符串「processName」傳遞的進程列表字符串「的grep processName」。

「[p] rocessName」的縮寫將僅匹配「processName」,而不匹配字符串「grep [p] rocessName」。

+0

良好的觀察。 pgrep或''ps ax -o comm | grep -q -w commandName'',或者任何數量的shellisms都可以。但這些是關於OP的問題的評論,不是解答... – pilcrow 2009-11-11 15:04:36