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

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

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

Например:

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

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

решение1

Скрипт 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

решение2

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

Почему?

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

Так как же мне надежно протестировать определенный запущенный процесс?

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

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

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

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

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

В этом случае используйте lockfile или 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 ...

ВидетьЧасто задаваемые вопросы по Башу 45для других способов запирания.

решение3

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

#!/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 ::Сравнение строк

Руководства по Ubuntuпгреп

решение4

Продолжая идею @rommel-cid, вы можете использовать pidofс || (||) для запуска команды, если процесс не существует, и && для запуска чего-либо, если процесс существует, таким образом создавая быстрое условие if/then/else. Например, вот один с запущенным процессом (мой браузер Chrome, имя процесса которого "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
$

Связанный контент