2012-02-01 3 views
4

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

Я возиться с 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..... 

Я не понимаю, почему я m получает «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!" 
+0

Вставить вывод '$ ps -elf | grep processname' для процесса. –

+0

Как младшая кодировка nit, '[\' grep something | wc -l \ '-gt 0]' можно упростить только в 'grep something'. См. Далее http://partmaps.org/era/unix/award-example-backticks.html – tripleee

+0

Спасибо triplee. Так вы говорите, для этого: если [$ (п.с. -elf | Grep $ (кошка $ LockFile) | Grep $ ($ 0 базовое) | туалет -l) -gt 0] Замены для этого: , если [ $ (ps -elf | grep $ (cat $ LOCKFILE) | grep $ (basename $ 0))] Я правильно понял вас? – jared

ответ

3

Аргумент для 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

Спасибо Shiplu. У меня есть следующий в моем скрипте для создания файла блокировки: lockfile -r 0 -l 21600 $ LOCKFILE >> $ LOGFILE 2> & 1 \ || abort "ERROR! - Не удалось получить блокировку! Возможно, он уже запущен ..." Я добавлял деталь pgrep в качестве дополнительной проверки в случае, если был заблокирован файл, который не был удален после предыдущего выполнения. – jared

0

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

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

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

0

Put это в верхней части вашего сценария ...

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 

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

Смежные вопросы