Как проверить / запустить процесс | ошибка в скрипте
Если хотите проверить, запущен ли процесс, и запустите его, если нет. Мой скрипт ниже глючит и всегда говорит, что процесс запущен. Что случилось?
$ ./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
который печатает только процессы с заданным именем команды.