Пример реализации lock-файлов

Искусство написания bash скриптов. Делимся своими наработками
Ответить
Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Пример реализации lock-файлов

Сообщение ZEN » 23 дек 2013, 15:04

Собственно ниже скелет скрипта, который будет запускать определенную программу. А при повторном запуске скрипт будет убивать приложение. Ключевая особенность в том, что мы создаем lock-файл с PID процесса и с помощью pgrep проверяем существует ли такой процесс в системе. Это позволяет нам одним скриптом запускать и останавливать задачу. При желании скрипт можно модифицировать так, что бы он только запускал задачу, если она не запущена.

Смотрим код:

Код: Выделить всё

#!/usr/bin/env bash

# Команда или скрипт, который нужно запустить
RUN_SCRIPT="cat /dev/zero > /dev/null";
# Lock-файл в котором будем хранить ID процесса (PID)
LOCK_FILE="/tmp/script.lock";
# Считываем из Lock-файла PID и проверяем 
# его наличие в процессах с помощью pgrep
# Если Lock-файл содержит несуществующий PID
# то в переменную PID ничего не будет записано
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);

# Проверяем переменную PID на содержимое
if [ $PID ] # Если PID содержит ID процесса
then
	# Убиваем процесс
    kill -SIGTERM $PID;
    # Удаляем Lock-файл
    rm $LOCK_FILE;
else # Если PID пустой
	# запускаем скрипт и сохраняем его PID
    $RUN_SCRIPT & PID=$!;
    # Записываем PID в Lock-файл
    echo $PID > $LOCK_FILE;
fi

# Завершаем работу скрипта с кодом 0
exit 0;
И пример работы скрипта:

Код: Выделить всё

zen@dev109:~$ ./script.sh ; ps aux | grep [z]ero || echo "Процесс не найден"
zen      17676  0.0  0.0   5740   544 pts/2    S    14:41   0:00 cat /dev/zero > /dev/null
zen@dev109:~$ ./script.sh ; ps aux | grep [z]ero || echo "Процесс не найден"
Процесс не найден
Как мы видим, если скрипт запущен, то мы видим строку с информацией кем он запущен и какой его PID. При повторном запуске скрипта процесс прерывается и уже в терминале мы видим информацию, что процесс не найден.

На этом всё. Дополнительно замечу, что создавать lock-файлы можно не вручную, а с помощью команд: lockfile-check, lockfile-create, lockfile-remove, lockfile-touch. Область применения lock-файлов зависит только от вас :)
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Аватара пользователя
olgmen
Сообщения: 155
Зарегистрирован: 30 ноя 2012, 11:00
Темы: 32
Откуда: Санкт-Петербург
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение olgmen » 23 дек 2013, 17:35

ZEN я включаю и выключаю usb-modem таким скриптом

Код: Выделить всё

#!/bin/bash
flag="/tmp/flag-modem"
if [ -f $flag ]; then
    for p in  `tail $flag`
    do
        poff megafon &
    done
    rm $flag
else
   pon megafon  &
   echo $! >> $flag
fi
без определения PID
Кто ищет, тот всегда найдет

Arch Linux
Conky - 1.9

Аватара пользователя
cadash
Сообщения: 292
Зарегистрирован: 27 авг 2013, 12:06
Темы: 59
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение cadash » 23 дек 2013, 18:44

А чем ваш способ запуска отличается от запуска демона? Или это такой новый подход?

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение ZEN » 23 дек 2013, 19:10

olgmen писал(а):ZEN я включаю и выключаю usb-modem таким скриптом

Код: Выделить всё

#!/bin/bash
flag="/tmp/flag-modem"
if [ -f $flag ]; then
    for p in  `tail $flag`
    do
        poff megafon &
    done
    rm $flag
else
   pon megafon  &
   echo $! >> $flag
fi
без определения PID
olgmen, в моем случае запускается avconv с помощью которого я могу записать видео с определенного окна (по клику по нему) или просто определенную произволбную область выделил. В моем случае нужно прибивать именно avconv, а не PID скрипта :). Именно потому я заношу его PID в lock-файл. Для решения задачи с модемом твой вариант тоже не плох.
cadash писал(а):А чем ваш способ запуска отличается от запуска демона? Или это такой новый подход?
Демон запускается, делает форк себя (запускает свою копию) и умирает. В моем случае не делается форк, запускается в фоне совсем другое приложение. Впрочем, совсем скоро я опубликую исходники скрипта для записи видео где всё это кому нужно будет станет понятным. скелет скрипта из первого поста я писал по обещанию, который выдал Серому ) Ему это для управления джаббер бота может пригодиться. Такие вот дела...
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Серый
Сообщения: 844
Зарегистрирован: 27 сен 2012, 19:20
Темы: 102
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение Серый » 23 дек 2013, 20:56

ZEN, я брагодарен тебе за инфу (в которой я пока не разобрался, мне нужно на это время), но мне интересно чем твой метод лучше моего простого примитивного однострочного скрипта? (который ты же мне и помог написать)

Код: Выделить всё

ps -Af | grep -i black | awk '{print $2}' | xargs kill ; /root/./BlackSmith-r178/BlackSmith.py
P.S. Кстати обожаю однострочные скрипты, какими бы они не были длинными. Всё что больше одной строки - это в моём понимании программа, а это не для меня, сложновато будет )
P.S.2. Ты уж извини если ответ на мой вопрос кроется в твоих ответах выше, если так, то мне надо попроще объяснять :)

Аватара пользователя
ZEN
Администратор
Сообщения: 1358
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение ZEN » 23 дек 2013, 21:30

Серый писал(а):ZEN, я брагодарен тебе за инфу (в которой я пока не разобрался, мне нужно на это время), но мне интересно чем твой метод лучше моего простого примитивного однострочного скрипта? (который ты же мне и помог написать)

Код: Выделить всё

ps -Af | grep -i black | awk '{print $2}' | xargs kill ; /root/./BlackSmith-r178/BlackSmith.py
P.S. Кстати обожаю однострочные скрипты, какими бы они не были длинными. Всё что больше одной строки - это в моём понимании программа, а это не для меня, сложновато будет )
P.S.2. Ты уж извини если ответ на мой вопрос кроется в твоих ответах выше, если так, то мне надо попроще объяснять :)
Да все нормально, я объясню) Информацию из моего скрипта можно использовать для написания init скрипта. Для debian-based систем можно посмотреть файл /etc/init.d/skeleton в котором уже написаны функции start/stop/restart. Всё, что нужно туда дописать - это работу с lock файлом как в моем примере выше. Это даст тебе возможно писать:
sudo service GudvinBot restat
и бот корректно завершит службу и запустит по новой, не запуская еще одну копию бота. Это очень гибко и удобно. А в будущем такие вещи можно писать не только для jabber-бота. И если захочешь через cron останавливать бота, тебе не нужно будет помнить этот однострочник. Достаточно будет в cron -e написать service GudvinBot restat в нужное время.
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Аватара пользователя
mivanchenko
Модератор
Сообщения: 14
Зарегистрирован: 27 ноя 2013, 17:00
Темы: 5
Контактная информация:
Статус: Не в сети

Re: Пример реализации lock-файлов

Сообщение mivanchenko » 10 фев 2015, 16:43

Ещё один вариант:

Код: Выделить всё

pkill -F $LOCK_FILE && rm $LOCK_FILE

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость