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

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

Например:

  • если процесс abc работает, сделайте это

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

Сценарий 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/nullthen    echo "Running"else    echo "Stopped"fi

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

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

if ! pgrep -x "gedit" > /dev/nullthen    echo "Stopped"fi

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

Почему?

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

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

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

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

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

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

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

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

#!/usr/bin/env bashif ! mkdir /tmp/abc.lock; then    printf "Failed to acquire lock.\n" >&2    exit 1fitrap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit# rest of script ...

Видеть Часто задаваемые ВОПРОСЫ по Bash 45 для других способов блокировки.

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

#!/bin/bash#check if abc is runningif pgrep abc >/dev/null 2>&1  then     # abc is running  else     # abc is not runningfi

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


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

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

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

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

Развивая идею @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$
## 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 runningif _isRunning gedit; then    echo "gedit is running"else    echo "gedit is not running"fi## example 2: start lxpanel if it is not thereif ! _isRunning lxpanel; then    lxpanel &fi## or_isRunning lxpanel || (lxpanel &)

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

Ни одно из "простых" решений не сработало для меня, потому что двоичный файл, который мне нужно проверить, не установлен в масштабах всей системы, поэтому я должен проверить с помощью path, что, в свою очередь, требует использования ps -ef | grep подход:

app="$_sdir/Logic 1.2.18 (64-bit)/Logic"app_pid=`ps -ef | grep "$app" | awk '{print $2}'`if `ps -p $app_pid > /dev/null`; then    echo "An instance of logic analyzer is appear to be running."    echo "Not starting another instance."    exit 5else    nohup "$app" &> /dev/null &fi

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

С помощью start-stop-daemon:

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

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

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

Решение Джона Врбанака не сработало, чтобы проверить, запущен ли PHP-процесс или нет для меня, я использую CentOS 7.

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

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

Допустим, в имени моего процесса была строка "Jane". Это позволит определить, запущен он или нет. Это работает для скриптов BASH и PHP.

ps -aux | grep "[J]ane" > /dev/null 2>&1if [[ "$?" == "0" ]]; then    echo "It's running"else    echo "It's not running"fi

Считаю важным отметить, что ни одно из приведенных ниже решений не учитывает состояние процесса. Комментарий к одному из моих вопросов привел меня сюда, но ответ на нем я попал в другое состояние программы, например, в “зомби-процесс” (не то, что я бы описал как “запущенный” процесс). Полный список значений столбца STAT в выходных данных ps приведен здесь для тех, кто склонен написать ответ, который учитывает это, или отредактировать свой собственный.

Обсуждение по теме: How can I prevent 'grep' from showing up in ps results? - Unix & Linux Stack Exchange

лучший способ проверить, существует ли процесс: bash - How to check if a process id (PID) exists - Stack Overflow

По pid: bash - How to check if a process id (PID) exists - Stack Overflow

По пути: linux - Check if a program in a specific path is running - Stack Overflow