2015-07-13 3 views
1

В настоящее время я создаю папку блокировки, которая создается при запуске моего сценария, и я также перемещаю файлы в подпапки здесь для обработки. Когда скрипт заканчивается, вызывается TRAP, который удаляет папку и содержимое блокировки, все из которых работает нормально. У нас была проблема на днях, когда кто-то вытащил власть с одного из серверов, поэтому мой TRAP никогда не вызывался, поэтому при повторной загрузке папки блокировки все еще было, что означало, что мои скрипты не могли возобновиться, пока они не будут удалены вручную. Каков наилучший способ проверить, запущен ли скрипт? Я в настоящее время этот подход с использованием процесса идентификаторов:Создание файла блокировки файлов

if ! mkdir $LOCK_DIR 2>/dev/null; then # Try to create the lock dir. This should pass successfully first run. 
    # If the lock dir exists 
    pid=$(cat $LOCK_DIR/pid.txt) 
    if [[ $(ps -ef | awk '{print $2}' | grep $pid | grep -v grep | wc -l) == 1 ]]; then 
     echo "Script is already running" 
     exit 1 
    else 
     echo "It looks like the previous script was killed. Restarting process." 
     # Do some cleanup here before removing dir and re-starting process. 

    fi 
fi 

# Create a file in the lock dir containing the pid. Echo the current process id into the file. 
touch $LOCK_DIR/pid.txt 
echo $$ > $LOCK_DIR/pid.txt 

# Rest of script below 
+0

Check 'man 1 lockfile lockfile-check lockfile-create lockfile-remove lockfile-touch' – anishsane

+2

Используйте команду' flock'. 'man flock' содержит примеры – hek2mgl

+0

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

ответ

1

Проверка/proc/и cmdline - хороший вызов - тем более, что на данный момент вы просто проверяете, нет ли процесса с идентификатором процесса, а не если процесс на самом деле является вашим скриптом.

Вы все еще можете сделать это с помощью команды ps, которая предложила бы какую-то форму агностицизма платформы.

COMMAND=$(ps -o comm= -p $pid) 
if [[ $COMMAND == my_process ]] 
then 
    ..... 

Обратите внимание на аргументы командной строки, чтобы ограничить его командой только без заголовка.

+0

Выглядит хорошо! Вписывается в мою текущую реализацию и, похоже, решает мою проблему. Хотя имя процесса возвращено в формате «имя_проса». почему он пропускает расширение файла sh, но включает точку? –

+0

Возможно, я только что ответил. Похоже, что ps имеет ограничение на длину имени процесса? –

+0

Вы можете указать ширину столбца. Согласно странице man ps -o comm: 100 = -p $ pid должен это сделать. Но это не так. ps -o command = -p $ pid Дает вам полную команду, включая аргументы. –

0

Многие системы в настоящее время используют TMPFS для каталогов типа/TMP. Поэтому эти каталоги всегда будут удалены после перезагрузки.

Если вы используете файл pid, обратите внимание, что вы можете легко увидеть команду , работающую под этим pid, в /proc/$pid/cmdline и /proc/$pid/exe.

+0

К сожалению, учитывая нашу структуру сервера, я бы не захотел обработать в папке tmp. Так что в таком случае я мог бы заменить ps ниже, хотя я не думаю, что там можно многое выиграть? : ls/proc | grep $ pid | wc -l –

+0

Вам не нужно класть все в/tmp, просто файл блокировки. Вам не нужно 'ls/proc'. В каждом процессе есть каталог. Итак, 'cat/proc/$ pid/cmdline' показывает вам, какая команда pid $ pid запущена. – meuh

+0

Обратите внимание, что блокировки под Linux, как ожидается, будут находиться под символом '/ run/lock/...' в течение дня, который всегда удаляется между перезагрузками. –

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