Как определить, работает ли процесс или нет, и использовать его для создания условного сценария оболочки?

88

Как определить, запущен ли процесс или нет, а затем запустить скрипт bash на основе этого условия?

Например:

  • , если выполняется процесс abc , сделайте это

  • , если он не запущен, сделайте это.

задан Nirmik 29.06.2012 в 23:53
источник

12 ответов

144

Сценарий bash, чтобы сделать что-то подобное, выглядел бы примерно так:

#!/bin/bash

# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern. 

if pgrep -x "gedit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi

Этот скрипт просто проверяет, запущена ли программа gedit.

Или вы можете проверить, не запущена ли программа, как это:

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi
    
ответ дан John Vrbanac 30.06.2012 в 00:08
источник
32

Любое решение, использующее что-то вроде ps aux | grep abc или pgrep abc , ошибочно.

Почему?

Поскольку вы не проверяете, работает ли какой-либо конкретный процесс, вы проверяете, есть ли какие-либо процессы, которые выполняются, чтобы соответствовать abc . Любой пользователь может легко создать и запустить исполняемый файл с именем abc (или который содержит abc где-то в его имени или аргументах), что приводит к ложному срабатыванию вашего теста. Существуют различные варианты, которые вы можете применить к ps , grep и pgrep , чтобы сузить поиск, но вы по-прежнему не получите надежный тест.

Итак, как я могу надежно проверить определенный процесс?

Это зависит от того, для чего вам нужен тест.

Я хочу убедиться, что служба abc запущена, а если нет, запустите ее

Это то, для чего предназначены init и upstart. Они запустит сервис и обеспечат его сохранение pidfile в pidfile. Попробуйте снова запустить службу (через init или upstart), и она проверит pidfile и начнет ее, если ее там нет, или прервется, если она уже запущена. Это все еще не на 100% надежнее, но оно как можно ближе.

См. Как проверить, установлен ли мой игровой сервер? все еще работает ... для других решений.

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

В этом случае используйте файл блокировки или lockdir. Например.

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

См. Bash FAQ 45 для других способов блокировки.

    
ответ дан geirha 30.06.2012 в 09:29
17

Это то, что я использую:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

В простом английском языке: , если 'pgrep' возвращает 0, процесс выполняется, в противном случае это не так.

Связанное чтение:

Bash Scripting :: Сравнение строк

Руководства Ubuntu pgrep

    
ответ дан Zuul 30.06.2012 в 00:15
5

Обычно у меня есть pidof -x $(basename $0) на моих скриптах, чтобы проверить, запущен ли он.

    
ответ дан Rommel Cid 14.01.2014 в 10:42
1

Riffing по идее @ rommel-cid, вы можете использовать pidof с || (||) для запуска команды, если процесс не существует и & amp; & amp; для запуска чего-то, если процесс существует, создавая тем самым быстрое if / then / else условное. Например, вот один из них с запущенным процессом (мой браузер Chrome, имя процесса которого «хром») и одно тестирование для процесса, которого не существует. Я подавил стандартный вывод с использованием 1 > / dev / null, чтобы он не печатал:

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$
    
ответ дан yuvilio 02.03.2014 в 00:08
0

Первое, что пришло мне в голову в связи с вашей проблемой:
ps aux | grep -i abc покажет детали процесса, если он работает. Вы можете сопоставить количество строк или времени, в течение которых оно выполняется и сравнивается с нулем или любыми другими манипуляциями. Когда вы запустите указанную выше команду, она покажет вам по крайней мере одну строку вывода, то есть подробно о процессе, созданном командой grep. Поэтому позаботьтесь об этом.
Это должно быть простым взломом. Поместите его в сценарий bash и посмотрите, полезен ли он.

    
ответ дан drake01 30.06.2012 в 00:03
0

Использование start-stop-daemon :

/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2

Он работает как обычный пользователь.

    
ответ дан Martin Monperrus 19.06.2015 в 19:55
0

Я обнаружил, что принятый ответ, отправленный @John Vrbanac, не работал для меня, и что ответ, отправленный @geirha, не отвечает на исходный вопрос.

Решение John Vrbanac не помогло проверить, работает ли PHP-процесс или нет, я запускаю CentOS 7.

Ответ

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

Вот что сработало для меня:

Скажите, что мой процесс имел строку «Jane» в названии процесса. Это найдет, если оно работает или нет. Это работает для сценариев BASH и PHP.

ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
    echo "It's running"
else
    echo "It's not running"
fi
    
ответ дан Wayne Workman 11.11.2016 в 20:12
0
## bash

## function to check if a process is alive and running:

_isRunning() {
    ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}

## example 1: checking if "gedit" is running

if _isRunning gedit; then
    echo "gedit is running"
else
    echo "gedit is not running"
fi

## example 2: start lxpanel if it is not there

if ! _isRunning lxpanel; then
    lxpanel &
fi

## or

_isRunning lxpanel || (lxpanel &)

Примечание : pgrep -x lxpanel или pidof lxpanel по-прежнему сообщает, что lxpanel работает, даже если он не работает (зомби); поэтому для того, чтобы получить живой и запущенный процесс, нам нужно использовать ps и grep

    
ответ дан Bach Lien 23.12.2017 в 19:01
-1

По состоянию на 23 сентября 2016 года pgrep, по-видимому, требует вариант «-x», чтобы скрипт muru работал.

#!/bin/bash

if pgrep -x "conky" > /dev/null 2>&1
then
  echo "conky running already"
else
  echo "now starting conky"
  conky
fi
exit 0

Я попробовал и протестировал вышеуказанный скрипт на машине Ubuntu 16.04.1. Наслаждайтесь!

    
ответ дан dzmanto 23.09.2016 в 20:39
-1
#!/bin/bash
while [ true ]; do     # Endless loop.
  pid='pgrep -x ${1}'  # Get a pid.
  if [ -z $pid ]; then # If there is none,
    ${1} &             # Start Param to background.
  else
    sleep 60           # Else wait.
  fi
done
    
ответ дан user7449824 28.01.2017 в 19:36
-3

isProcessRunning () {если [$ (pidof $ 1) > / dev / null]; затем retval = 'true'; else retval = 'false'; Fi; echo $ retval; }

isProcessRunning geany

True

    
ответ дан Dominic 19.01.2016 в 20:37