2010-05-25 3 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 

версия Bash: GNU Баш, версия 3.2.25 (1) -release (x86_64-RedHat-Linux-гну)

+0

Лучший способ проверить, существует ли процесс: http: // stackoverflow.com/questions/3043978/how-to-check-if-a-process-id-pid-exists –

+0

Не могли бы вы просто проверить, не получите ли вы пустой результат из команды grep вместо того, чтобы полагаться на возвращаемые значения? –

+0

Я пробовал это и имею аналогичную проблему. Выход не учитывается. Вот код: #/бен/Баш SERVICE = $ 1 OUTPUT = $ (п.с. -a | Grep -v Grep | Grep $ 1) эхо $ OUTPUT , если [ "$ {# OUTPUT}" - gt; 0]; затем echo «' date': $ SERVICE работает, все в порядке » еще echo« 'date': $ SERVICE не работает» fi – elasticsecurity

ответ

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

+0

Пробовал работать с #!/Bin/sh -x, чтобы посмотреть на процесс выполнения? – Anders

+0

ничего особенного: выход не + Сервис = рельсы + PS -a + Grep Grep -v + Grep Рельсы + Результат = 1 + эхо 'код выхода: 1' код выхода: 1 + ['1 -eq 0'] ' ++ date + echo' Вт Май 25 06:52:25 EDT 2010: рельсы не работают ' – elasticsecurity

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

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

Как я могу сделать то же самое, но без вывода PID из pgrep на консоль? – Kostanos

+5

Используйте это 'pgrep procname>/dev/null && echo Running', чтобы избежать pgrep, выводящего PID – Kostanos

+1

«killall -q» не произнесет ни слова – Andor

4

Проверьте, если ваше имя сценарии не содержит $ SERVICE. Если да, то это будет показано в результатах 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

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 «FireFox» и это шины все более красиво, а затем переходит к убить ,

# -- 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

Несмотря на некоторый успех с использованием метода/dev/null в bash. Когда я подтолкнул решение к cron, он потерпел неудачу. Однако проверка размера возвращенной команды отлично работала. Амперранд позволяет 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

0

мне нужно сделать, это время от времени, и в конечном итоге взлома командной строки, пока она не работает.

Например, здесь я хочу увидеть, если у меня есть какие-либо SSH соединения, (8-й столбец, возвращаемый «пс» это работает «путь к PROCNAME» и фильтруется «AWK»:

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

Тогда я положил его в раковине-скрипте («Eval» -ный командную строку внутри обратных кавычек), например:

#!/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 

«СЭД» часть наличники пути к точному маркеру и может потребоваться для ваших нужд.

Вот мой пример, который я использовал для получения вашего ответа. Я написал его для автоматического создания 2 туннелей SSH и запуска VNC-клиента для каждого.

Я запустил его из своей оболочки Cygwin, чтобы выполнить администрирование на моем сервере с рабочей станции Windows, поэтому я могу перейти к UNIX/LINUX-земле с помощью одной команды (это также предполагает, что ключи клиента rsa уже были «ssh- copy-id "-ed и известны удаленному хосту).

Это идемпотент в том, что каждая команда proc/запускается только при их $ VAR eval в пустую строку.

Он добавляет «| wc -l», чтобы сохранить количество запущенных процессов, которые соответствуют (то есть количество найденных строк), вместо proc-name для каждого $ VAR в соответствии с моими потребностями. Я сохраняю инструкции «эхо», чтобы я мог повторно запустить и диагностировать состояние обоих соединений.

#!/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 

Это очень жемчужно-как мне и, возможно, более, чем Unix Utils истинных сценарии оболочки. Я знаю, что есть много «MAGIC» чисел и cheezy жестко закодированных значений, но он работает (я думаю, что у меня тоже плохой вкус для использования слишком большого количества UPPERCASE). Гибкость может быть добавлена ​​с некоторыми аргументами cmd-line, чтобы сделать это более универсальным, но я хотел поделиться тем, что сработало для меня. Пожалуйста, улучшайте и делитесь. Приветствия.

0

Решение с service и awk, которое принимает список наименований услуг, разделенных запятой.

Прежде всего, это, вероятно, хорошая ставка, вам понадобятся права 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 
Смежные вопросы