Как я могу определить, запущен процесс или нет, а затем выполнить сценарий 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/null
then
echo "Running"
else
echo "Stopped"
fi
Этот скрипт просто проверяет, запущена ли программа "gedit".
Или вы можете только проверить, работает ли программа следующим образом:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
/dev/null
: "/ dev / null перенаправляет стандартный вывод команды на нулевое устройство, которое является специальным устройством, которое отбрасывает записанную в него информацию" ... использование 0
перенаправит вывод команды в файл с именем 0
. В этом случае я бы посоветовал почувствовать себя более комфортно > /dev/null
- вы увидите это повсюду, так как это стандартный / правильный способ отменить вывод.
-x
параметр, чтобы pgrep
он искал точное приложение, иначе он получит неверное значение, если найдет ту же строку в имени другого приложения. Я просто потратил 1 час, чтобы выяснить это.
! pgrep
Любое решение, которое использует что-то вроде ps aux | grep abc
или pgrep abc
имеет недостатки.
Поскольку вы не проверяете, запущен ли конкретный процесс, вы проверяете, запущены ли какие-либо процессы, которые совпадают abc
. Любой пользователь может легко создать и запустить исполняемый файл с именем abc
(или содержащий abc
его в своем имени или аргументах), что приведет к ложному срабатыванию вашего теста. Есть различные варианты , которые можно применить к ps
, grep
и pgrep
сузить область поиска, но вы все равно не получите надежный тест.
Это зависит от того, для чего вам нужен тест.
Для этого и нужны init и upstart. Они запустят службу и гарантируют, что ее pid будет сохранен в pidfile. Попробуйте снова запустить службу (через init или upstart), и она проверит pid-файл и либо запустит его, если его там нет, либо прервет работу, если он уже запущен. Это все еще не на 100% надежно, но это так близко, как вы получите.
Посмотрите, как я могу проверить, работает ли мой игровой сервер ... для других решений.
В этом случае используйте файл блокировки или файл блокировки. Например
#!/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 для других способов блокировки.
pgrep
или ps
вполне адекватно, и ваш подход кажется излишним. Если вы пишете сценарий для публичного распространения, вы должны писать его максимально безопасным способом.
rm
команда запускается. Так что, пока он заканчивается после того, как ловушка установлена, замок должен исчезнуть.
Это то, что я использую:
#!/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
pgrep
имеет ту же «особенность» ограничения в 15 символов, о которой упоминалось ранее, поэтому, например pgrep gnome-power-manager
, также потерпит неудачу
-x
опцию pgrep : «Только сопоставлять процессы, чье имя (или командная строка, если указан -f) точно соответствует шаблону».
У меня обычно есть 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
$
Ни одно из «простых» решений не сработало для меня, потому что бинарный файл, который мне нужно проверить, не установлен в масштабе всей системы, поэтому я должен проверить с помощью пути, что, в свою очередь, требует использования 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 5
else
nohup "$app" &> /dev/null &
fi
Первое, что пришло мне в голову по вашей проблеме:
ps aux | grep -i abc
покажет детали процесса, если он запущен. Вы можете сопоставить количество строк или время, в течение которого он работает, и сравнить его с нулем или любой другой манипуляцией. Когда вы запустите указанную выше команду, она покажет вам по крайней мере одну строку вывода, т.е. подробную информацию о процессе, созданном командой thi 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 только гарантирует, что экземпляр еще не запущен, прежде чем запускать другой. Это не был первоначальный вопрос, первоначальный вопрос состоял в том, чтобы проверить, запущен процесс или нет.
Вот что сработало для меня:
Скажем, у моего процесса была строка «Джейн» в имени процесса. Это найдет, работает он или нет. Это работает для скриптов 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
## 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
По состоянию на 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. Наслаждайтесь!
#!/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
zombie
процессе (не то, что я бы назвал «запущенным» процессом). Полный списокSTAT
значений столбцов в выходных данныхps
приведен здесь для тех, кто склонен написать ответ, который учитывает это, или отредактировать свой собственный.