2010-05-25 185 views
53

我寫了一個bash腳本來檢查進程是否正在運行。它不起作用,因爲ps命令總是返回退出代碼1.當我從命令行運行ps命令時,$?被正確設置,但在腳本中它始終是1.任何想法?bash腳本來檢查運行進程

#!/bin/bash 
SERVICE=$1 

ps -a | grep -v grep | grep $1 > /dev/null 
result=$? 
echo "exit code: ${result}" 
if [ "${result}" -eq "0" ] ; then 
    echo "`date`: $SERVICE service running, everything is fine" 
else 
    echo "`date`: $SERVICE is not running" 
fi 

猛砸版本:GNU的bash,版本3.2.25(1)-release下(x86_64-紅帽Linux的GNU的)

+0

檢查過程是否存在的最佳方法:http:// stackoverflow。com/questions/3043978/how-to-check-if-a-process-id-pid-exists – 2016-06-07 15:43:48

+0

你能否檢查一下,看看你是否從grep命令獲得非空輸出而不是依賴返回值? – 2010-05-25 09:22:17

+0

我試過這個,並有類似的問題。輸出不被考慮在內。下面的代碼: #/斌/慶典 SERVICE = $ 1 OUTPUT = $(PS -a | grep的-v grep的| grep的$ 1) 回聲$ OUTPUT 如果[ 「$ {#OUTPUT}」 - gt 0];然後 echo「'date':$ SERVICE service running,everything is fine」 else echo「'date':$ SERVICE is not running」 fi – elasticsecurity 2010-05-25 09:44:13

回答

12

試戴BASH版本3.2.29您的版本,運行良好。不過,你可以按照上面的建議做一些事情,例如:

#!/bin/sh 

SERVICE="$1" 
RESULT=`ps -a | sed -n /${SERVICE}/p` 

if [ "${RESULT:-null}" = null ]; then 
    echo "not running" 
else 
    echo "running" 
fi 
+0

我試過了,也不行。我的環境一定有些可疑(共享主機提供商)。 – elasticsecurity 2010-05-25 10:00:20

+0

嘗試使用#!/ bin/sh -x來查看執行過程? – Anders 2010-05-25 10:03:49

+0

沒有什麼特別的:輸出是 + SERVICE =導軌 + PS -a +的grep -v grep的 + grep的導軌 +導致= 1 +回波 '退出代碼:1' 退出代碼:1 +' ''1 -eq 0']' ++ date + echo'Tue May 25 06:52:25 EDT 2010:rails is not running' – elasticsecurity 2010-05-25 10:53:14

1

我發現了這個問題。 ps -ae改爲ps -a的作品。

我想這與我在共享主機環境中的權利有關。從命令行執行「ps -a」和在bash腳本中執行它之間顯然有區別。

4

工作一。

 
!/bin/bash 
CHECK=$0 
SERVICE=$1 
DATE=`date` 
OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1) 
echo $OUTPUT 
if [ "${#OUTPUT}" -gt 0 ] ; 
then echo "$DATE: $SERVICE service running, everything is fine" 
else echo "$DATE: $SERVICE is not running" 
fi 
+0

pgrep是一個更好的解決方案,你仍然有問題,你不檢查進程名稱,但ps aux的整個輸出。 – karsten 2018-01-12 12:02:13

3
 
#!/bin/bash 
ps axho comm| grep $1 > /dev/null 
result=$? 
echo "exit code: ${result}" 
if [ "${result}" -eq "0" ] ; then 
echo "`date`: $SERVICE service running, everything is fine" 
else 
echo "`date`: $SERVICE is not running" 
/etc/init.d/$1 restart 
fi 

像這樣的事情

90

有幾個非常簡單的方法:

pgrep procname && echo Running 
pgrep procname || echo Not running 
killall -q -0 procname && echo Running 
pidof procname && echo Running 
+0

我怎樣才能做到這一點,但沒有從pgrep輸出到控制檯的PID? – Kostanos 2013-08-06 19:21:38

+5

使用''pgrep procname>/dev/null && echo Running'來避免pgrep輸出PID – Kostanos 2013-08-06 19:27:50

+1

「killall -q」不會說一個字 – Andor 2013-09-27 14:05:50

4

檢查你的腳本名稱不包含$服務。如果確實如此,它將以ps結果顯示,導致腳本始終認爲該服務正在運行。你可以像這樣用當前文件名grep它:

#!/bin/sh 
SERVICE=$1 
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null 
then 
    echo "$SERVICE service running, everything is fine" 
else 
    echo "$SERVICE is not running" 
fi 
+1

對於那些希望將其用作腳本的一部分,而不是作爲函數,將$ 0更改爲grep 'ps ax | grep -v grep | grep -v grep | grep $ SERVICE>/dev/null' – NullVoxPopuli 2013-07-09 13:34:34

2

這些是有用的提示。我只需要知道在啓動腳本時服務是否正在運行,因此當我離開時我可以將服務保持在同一狀態。最後我用這樣的:

HTTPDSERVICE=$(ps -A | grep httpd | head -1) 

    [ -z "$HTTPDSERVICE" ] && echo "No apache service running." 
8

我用這個來檢查每10秒進程正在運行,如果沒有啓動,並允許多個參數:

#!/bin/sh 

PROCESS="$1" 
PROCANDARGS=$* 

while : 
do 
    RESULT=`pgrep ${PROCESS}` 

    if [ "${RESULT:-null}" = null ]; then 
      echo "${PROCESS} not running, starting "$PROCANDARGS 
      $PROCANDARGS & 
    else 
      echo "running" 
    fi 
    sleep 10 
done  
1

安道爾的上述之一的一個簡單的腳本版本建議:

!/bin/bash 

pgrep $1 && echo Running 

如果上面的腳本名爲test.sh然後,爲了試驗,型式: test.sh NameOfProcessToCheck

例如 test.sh php

6

這個技巧適用於我。希望這可以幫助你。讓我們將以下保存爲checkRunningProcess.sh

#!/bin/bash 
ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0` 
result=$(echo $ps_out | grep "$1") 
if [[ "$result" != "" ]];then 
    echo "Running" 
else 
    echo "Not Running" 
fi 

充分利用checkRunningProcess.sh executable.And然後使用它。
使用示例。

20:10 $ checkRunningProcess.sh proxy.py 
Running 
20:12 $ checkRunningProcess.sh abcdef 
Not Running 
0

我在想,如果這將是有進步的企圖的過程是一個好主意,讓你通過這個FUNC進程名稱func_terminate_process「火狐」,它的輪胎東西更漂亮,然後再轉移到殺。

# -- NICE: try to use killall to stop process(s) 
killall ${1} > /dev/null 2>&1 ;sleep 10 

# -- if we do not see the process, just end the function 
pgrep ${1} > /dev/null 2>&1 || return 

# -- UGLY: Step trough every pid and use kill -9 on them individually 
for PID in $(pidof ${1}) ;do 

    echo "Terminating Process: [${1}], PID [${PID}]" 
    kill -9 ${PID} ;sleep 10 

    # -- NASTY: If kill -9 fails, try SIGTERM on PID 
    if ps -p ${PID} > /dev/null ;then 
     echo "${PID} is still running, forcefully terminating with SIGTERM" 
     kill -SIGTERM ${PID} ;sleep 10 
    fi 

done 

# -- If after all that, we still see the process, report that to the screen. 
pgrep ${1} > /dev/null 2>&1 && echo "Error, unable to terminate all or any of [${1}]" || echo "Terminate process [${1}] : SUCCESSFUL" 
4

儘管在bash中/ dev/null方法取得了一些成功。當我將解決方案推向cron時,它失敗了。雖然檢查返回的命令的大小工作完美。 ampersrand允許bash退出。

#!/bin/bash 
SERVICE=/path/to/my/service 
result=$(ps ax|grep -v grep|grep $SERVICE) 
echo ${#result} 
if ${#result}> 0 
then 
     echo " Working!" 
else 
     echo "Not Working.....Restarting" 
     /usr/bin/xvfb-run -a /opt/python27/bin/python2.7 SERVICE & 
fi 
-1

最簡單的檢查,按進程名:

bash -c 'checkproc ssh.exe ; while [ $? -eq 0 ] ; do echo "proc running";sleep 10; checkproc ssh.exe; done' 
+0

這看起來像一個Windows解決方案,而不是一個很好的解決方案。你能鏈接到'checkproc'的文檔嗎? – tripleee 2017-10-31 05:15:03

0

我需要從時間做到這一點時間,並最終黑客命令行,直到它的工作原理。

例如,在這裏我想看看我是否有任何SSH連接(由「PS」返回第八欄是運行「路徑到PROCNAME」,並通過「AWK」過濾:

ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' 

然後我把它放在一個外殼腳本,(「EVAL」 -ing反引號內的命令行),這樣的:

#!/bin/bash 

VNC_STRING=`ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g'` 

if [ ! -z "$VNC_STRING" ]; then 
    echo "The VNC STRING is not empty, therefore your process is running." 
fi 

的「sed的」部分修剪的確切令牌的路徑和可能並不需要您的需求。

這是我用來獲得答案的示例。我寫它自動創建2個SSH隧道併爲每個客戶端啓動一個VNC客戶端。我也可以用一個命令跳到UNIX/LINUX-land(這也假定客戶端的rsa鍵已經是「ssh-key」), copy-id「-ed並且對遠程主機是已知的)。

它的冪等性在於每個proc /命令僅在其$ VAR eval爲空字符串時觸發。

它附加「| wc -l」來存儲匹配的正在運行的proc的數量(即找到的行數),而不是每個$ VAR的proc-name以滿足我的需要。我保留「回聲」語句,以便我可以重新運行並診斷兩個連接的狀態。

#!/bin/bash 

SSH_COUNT=`eval ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' | wc -l` 
VNC_COUNT=`eval ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g' | wc -l` 

if [ $SSH_COUNT = "2" ]; then 
    echo "There are already 2 SSH tunnels." 
elif [ $SSH_COUNT = "1" ]; then 
    echo "There is only 1 SSH tunnel." 
elif [ $SSH_COUNT = "0" ]; then 
    echo "connecting 2 SSH tunnels." 
    ssh -L 5901:localhost:5901 -f -l USER1 HOST1 sleep 10; 
    ssh -L 5904:localhost:5904 -f -l USER2 HOST2 sleep 10; 
fi 

if [ $VNC_COUNT = "2" ]; then 
    echo "There are already 2 VNC sessions." 
elif [ $VNC_COUNT = "1" ]; then 
    echo "There is only 1 VNC session." 
elif [ $VNC_COUNT = "0" ]; then 
    echo "launching 2 vnc sessions." 
    vncviewer.exe localhost:1 & 
    vncviewer.exe localhost:4 & 
fi 

這對我來說很像perl-like,可能比真正的shell腳本更多的是unix utils。我知道有很多「MAGIC」數字和cheezy硬編碼的價值,但它的工作原理,(我認爲我也使用這麼多大寫字母的口味不佳)。靈活性可以添加一些CMD線參數,使這更多功能,但我想分享什麼對我有用。請改善和分享。乾杯。

0

一個包含serviceawk的解決方案,它包含逗號分隔的服務名稱列表。

首先,它可能是一個很好的選擇,你需要root權限才能做你想做的事情。如果你不需要檢查,那麼你可以刪除該部分。

#!/usr/bin/env bash 

# First parameter is a comma-delimited string of service names i.e. service1,service2,service3 
SERVICES=$1 

ALL_SERVICES_STARTED=true 

if [ $EUID -ne 0 ]; then 
    if [ "$(id -u)" != "0" ]; then 
    echo "root privileges are required" 1>&2 
    exit 1 
    fi 
    exit 1 
fi 

for service in ${SERVICES//,/ } 
do 
    STATUS=$(service ${service} status | awk '{print $2}') 

    if [ "${STATUS}" != "started" ]; then 
     echo "${service} not started" 
     ALL_SERVICES_STARTED=false 
    fi 
done 

if ${ALL_SERVICES_STARTED} ; then 
    echo "All services started" 
    exit 0 
else 
    echo "Check Failed" 
    exit 1 
fi