Как я могу определить, запущен ли процесс или нет, а затем заставить скрипт bash выполнить некоторые вещи на основе этого условия?
Например:
если процесс
abc
работает, сделайте этоесли он не запущен, сделайте это.
Как я могу определить, запущен ли процесс или нет, а затем заставить скрипт 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