Подтвердить что ты не робот

Bash скрипт для проверки запущенного процесса

Я написал bash - script, чтобы проверить, запущен ли процесс. Это не работает, так как команда ps всегда возвращает код выхода 1. Когда я запускаю команду ps из командной строки, $? правильно установлен, но внутри script он всегда 1. Любая идея?

#!/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 bash, версия 3.2.25 (1) -release (x86_64-redhat-linux-gnu)

4b9b3361

Ответ 1

Есть несколько действительно простых методов:

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

Ответ 2

Пробовал вашу версию на 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

Ответ 3

Этот трюк работает для меня. Надеюсь, это может вам помочь. Сохраните следующие значения как 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. Затем используйте его.
Пример использования.

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

Ответ 4

Я использую это для проверки каждые 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    

Ответ 5

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

Ответ 6

Рабочий.

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

Ответ 7

Несмотря на некоторый успех с использованием метода /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

Ответ 8

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

Что-то вроде этого

Ответ 9

Это полезные советы. Мне просто нужно было знать, работает ли служба при запуске script, поэтому я мог оставить службу в том же состоянии, когда я ушел. В итоге я использовал это:

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

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

Ответ 10

Я нашел проблему. ps -ae вместо ps -a работает.

Я предполагаю, что это связано с моими правами в среде совместного размещения. По-видимому, существует разница между выполнением "ps -a" из командной строки и выполнением ее из bash - script.

Ответ 11

Простая версия script одного из предложений Андора:

!/bin/bash

pgrep $1 && echo Running

Если вышеуказанный script называется test.sh, то для тестирования введите: test.sh NameOfProcessToCheck

например. test.sh php

Ответ 12

Мне было интересно, было бы неплохо иметь прогрессивные попытки в процессе, поэтому вы передаете это 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"

Ответ 13

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

Например, здесь я хочу посмотреть, есть ли у меня какие-либо SSH-соединения (8-й столбец, возвращаемый "ps", является запущенным "path-to-procname" и фильтруется "awk":

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

Затем я поместил его в оболочку script, ( "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

Часть "sed" выравнивает путь к точному токену и может не понадобиться для ваших нужд.

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

Я запускаю его из своей оболочки Cygwin, чтобы выполнить администрирование на моем сервере с моей рабочей станции Windows, поэтому я могу перейти на UNIX/LINUX-land с помощью одной команды (это также предполагает, что ключи клиента 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

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

Ответ 14

Решение с 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

Ответ 15

Самая простая проверка по имени процесса:

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