Определение, запущен ли процесс с использованием pgrep - PullRequest
4 голосов
/ 02 февраля 2012

У меня есть скрипт, который я хочу запускать только один раз.Если скрипт вызывается во второй раз, я проверяю, существует ли файл блокировки.Если файл блокировки существует, то я хочу посмотреть, действительно ли процесс запущен.

Я возился с pgrep, но не получаю ожидаемых результатов:

#!/bin/bash
COUNT=$(pgrep $(basename $0) | wc -l)
PSTREE=$(pgrep $(basename $0) ; pstree -p $$)
echo "###"
echo $COUNT
echo $PSTREE
echo "###"
echo "$(basename $0) :" `pgrep -d, $(basename $0)`
echo sleeping.....
sleep 10

Результаты, которые яЯ получаю:

$ ./test.sh  
###
2
2581 2587 test.sh(2581)---test.sh(2587)---pstree(2591)
###
test.sh : 2581
sleeping.....

Я не понимаю, почему я получаю «2», когда на самом деле работает только один процесс.

Есть идеи?Я уверен, что так я это называю.Я пробовал несколько различных комбинаций и, похоже, не могу понять это.

РЕШЕНИЕ:

Я закончил тем, что делал это (часть моего сценария):

function check_lockfile {
    # Check for previous lockfiles

    if [ -e $LOCKFILE ] 
    then
        echo "Lockfile $LOCKFILE already exists.  Checking to see if process is actually running...." >> $LOGFILE 2>&1
        # is it running?
        if [ $(ps -elf | grep $(cat $LOCKFILE) | grep $(basename $0) | wc -l) -gt 0 ]
        then
            abort "ERROR! - Process is already running at PID: $(cat $LOCKFILE).  Exitting..."
        else
            echo "Process is not running.  Removing $LOCKFILE" >> $LOGFILE 2>&1
            rm -f $LOCKFILE
        fi
    else
        echo "Lockfile $LOCKFILE does not exist." >> $LOGFILE 2>&1
    fi
}

function create_lockfile {
    # Check for previous lockfile
    check_lockfile

    #Create lockfile with the contents of the PID
    echo "Creating lockfile with PID:" $$ >> $LOGFILE 2>&1
    echo -n $$ > $LOCKFILE
    echo "" >> $LOGFILE 2>&1
}

# Acquire lock file
create_lockfile >> $LOGFILE 2>&1 \
|| echo "ERROR! - Failed to acquire lock!"

Ответы [ 3 ]

3 голосов
/ 02 февраля 2012

Аргументом для pgrep является шаблон расширенного регулярного выражения. В вашем случае команда pgrep $(basename $0) будет иметь значение pgrep test.sh, которое будет соответствовать любому процессу, в котором test сопровождается любым символом и, наконец, sh. Так что это будет соответствовать btest8sh, atest_shell и т. Д.

Вы должны создать файл блокировки. Если файл блокировки существует, программа должна завершиться.

lock=$(basename $0).lock
if [ -e $lock ] 
then 
    echo Process is already running with PID=`cat $lock`
    exit
else
    echo $$ > $lock
fi
0 голосов
/ 02 февраля 2012

Поместите это в верхнюю часть вашего скрипта ...

pid=$$
script=$(basename $0)
guard="/tmp/$script-$(id -nu).pid"
if test -f $guard ; then
    echo >&2 "ERROR: Script already runs... own PID=$pid"
    ps auxw | grep $script | grep -v grep >&2
    exit 1
fi
trap "rm -f $guard" EXIT
echo $pid >$guard

И да, есть небольшое окно для состояния гонки между командами test и echo, которое можно исправить, добавив в файл защиты, а затем убедившись, что первая строка действительно является нашим собственным PID. Кроме того, диагностический вывод в if может быть закомментирован в производственной версии.

0 голосов
/ 02 февраля 2012

Вы уже открываете файл блокировки.Используйте его, чтобы облегчить свою жизнь.

Запишите идентификатор процесса в файл блокировки.Когда вы увидите, что файл блокировки существует, прочитайте его, чтобы увидеть, какой идентификатор процесса он предположительно блокирует, и проверьте, работает ли этот процесс.

Затем в версии 2 вы также можете написать имя программыаргументы, время запуска программы и т. д. для защиты от случая, когда новый процесс начинается с тем же идентификатором процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...