Как проверить / запустить процесс | ошибка в скрипте
Если хотите проверить, запущен ли процесс, и запустите его, если нет. Мой скрипт ниже глючит и всегда говорит, что процесс запущен. Что случилось?
$ ./check_n_run thisisnotrunning
./check_n_run: thisisnotrunning is already running
Вот сценарий:
$ cat check_n_run
#!/bin/sh
USAGE="usage: $0 processname"
if [ $# -ne 1 ] ; then
echo "$USAGE" >&2
exit 1
fi
ps ax | grep -v grep | grep $1> /dev/null
if [ $? -eq 1 ]
then
echo "$1 not running"
# start here
else
echo "$0: $1 is already running" >&2
fi
exit 0
4 ответа
Проблема в вашем сценарии заключается в том, что (с используемой оболочкой) в конвейере каждая команда выполняется в отдельной подоболочке, и ни один из их статусов не передается в родительский процесс. Так после command1 | command2
, $?
всегда 0.
Даже если вы исправили это, ваш сценарий крайне ненадежен: он будет сопоставлять процессы с именем, которое содержит ваш процесс в качестве подстроки. Linux предоставляет pidof
Команда, которая делает именно то, что вы пытаетесь сделать.
Однако это все еще не идеально, потому что может быть другой процесс с тем же именем. Было бы лучше использовать надлежащий супервизор службы, такой как Debian/Ubuntu start-stop-daemon
или выскочка службы. lockfile
(из procmail), упомянутый Wrikken, также возможен.
Я думаю, что вы попробовали трудный путь. Я не знаю, какой дистрибутив вы используете, но постараюсь увидеть путь /var/run
, Это каталог, включающий pid каждого процесса.
Просто попробуй ls *something*
, Если что-то возвращается, значит, ваш процесс запущен. В противном случае это не так.
Пока ps / grep не выдает ошибку, $? должно быть 0.
редактировать: в соответствии с Жилем (у меня нет ни одной доступной оболочки):
в кш / зш, $? будет 1, если grep не найдет совпадения или не допустит ошибку
Я обычно склонен использовать lockfile
в запуске этих процессов...
lockfile /path/to/lockfile && (do_something; rm -f /path/to/lockfile)
Хотя ваш сценарий может быть изменен на:
procs=`ps ax | grep -v grep | grep -c $1`
if [ $procs -lt 1 ]
then
....
Проблема: если ваша система похожа на мою, вывод ps ax
включает не только имя процесса, но и всю командную строку, используемую для его запуска. Поэтому, когда вы бежите
./check_n_run thisisnotrunning
выход ps ax
будет буквально включать эту строку, так grep
всегда найдет результат для thisisnotrunning
, Это объясняет, почему ваш скрипт всегда сообщает, что программа запущена.
Чтобы обойти это, есть несколько вариантов. Как отметил Жиль, лучше всего использовать start-stop-daemon
запустить и остановить ваш скрипт. Если это не возможно, вы можете использовать pidof
определить, запущен ли данный исполняемый файл. И если по какой-то причине это было недоступно, вы можете использовать
ps -C thisisnotrunning
который печатает только процессы с заданным именем команды.