LINUX.ORG.RU

lockfile для скрипта

 , ,


1

1

Ситуация:

есть скрипт, которые может создавать директорию, переходить в нее и делать там всякое (директория берется из параметров).

Таких скриптов может одновременно быть запущенна пачка, и каждый будет копошиться в своей директории.

Надо сделать так, чтобы при натравливании скрипта на директорию, в которой уже орудует его собрат, новый орал, что там уже кто-то работает и завершался, т.е. чтобы каждый скрипт держал некий уникальный lockfile.

Прочитал кучу манов, но механизма создания и взаимодействия скриптов так и не понял.

Пробовал lockfile-progs из разных терминалов. Локи удалялись без проблем. В примерах с flock номер файла задавался жестко.

Помогите разобраться, я тупой. :(

★★★★★
main() {
  echo делаем бесполезную работу
}

test -d "$@" || {
  echo "$@" is not a directory
  exit
}

test -a "$@/script.lock" && {
  echo $0 is already running in "$@" directory
  exit
}
> "$@/script.lock"

main "$@"

rm "$@/script.lock"
Spoofing ★★★★★
()
Последнее исправление: Spoofing (всего исправлений: 1)

Мне не понятна твоя проблема. Скрипт должен проверять наличие lock файла.

Локи удалялись без проблем.

А не должны?

Black_Shadow ★★★★★
()
#!/bin/sh

main() {
  echo делаем бесполезную работу
}

die() {
  rm "$@/script.lock"
}

test -d "$@" || {
  echo "$@" is not a directory
  exit
}

test -a "$@/script.lock" && {
  echo $0 is already running in "$@" directory
  exit
}
> "$@/script.lock"

trap die INT

main "$@"

die "$@"
Spoofing ★★★★★
()
Последнее исправление: Spoofing (всего исправлений: 1)
Ответ на: комментарий от Black_Shadow

trap пусть отлавливает сигналы отправленные kill'ом. допишет сам какие ему надо. =)

Spoofing ★★★★★
()

формулировка судя по всему невнятная/неполная, иначе всё решалось бы просто проверкой существования директории

zolden ★★★★★
()
Ответ на: комментарий от Black_Shadow

Если скрипт прибить с помощью kill, или просто ctrl+c, то lock останется.

Но в целом-то направление мысли правильное. Нужно только писать в script.lock pid процесса, и при запуске проверять, существует ли такой процесс

Deleted
()
Ответ на: комментарий от Deleted

Угу, но иногда пид процесса мёр^W свободен, а дело скрипта живёт, ЕВПОЧЯ. Не говоря о том, что пид может быть УЖЕ от другого процесса.

GreyDoom ★★★★
()

Смысл такой:

Запускается один скрипт, создаёт lock-файл, делает свою работу, удаляет lock-файл.

Запускается второй скрипт, пытается создать тот же lock-файл, обламывается, ругается, завершается.

Директория может существовать изначально, т.е. скрипт может обновлять её содержимое.

Про trap надо подумать. Не знал про такой механизм.

Я не совсем понимаю механизма работы lock-файлов. Они как флаги работают, или им какие-то системные переменные соответствуют? Ну типа как сокеты. Т.е. возможна ли ситуация, что lock-файл есть, а лока как такового нет?

Radjah ★★★★★
() автор топика
Ответ на: комментарий от GreyDoom

пид процесса мёр^W свободен, а дело скрипта живёт

А как это можно обойти?

пид может быть УЖЕ от другого процесса

Ну, вероятность такого на стабильно работающей системе не очень же высока?

Мне кажется лучше остановиться на какой-то простой схеме и дорабатывать по ситуации. Все равно всего не предусмотришь

Deleted
()
Ответ на: комментарий от Deleted

А как это можно обойти?

Логикой скрипта или отказом от баша.

вероятность такого на стабильно работающей системе не очень же высока?

Даже КРАЙНЕ МАЛА. Но какое это будет иметь значение, когда это это продакшн 24x7 и.. и ещё догадайся потом, что причина аварии была именно в этом. Из таких вон редких случаев и выходят невоспроизводимые глюки, магические поломки и лечения ребутом..

GreyDoom ★★★★
()
Ответ на: комментарий от GreyDoom

когда это это продакшн 24x7

успокойся, это лор, тут никто кроме локалхоста в жизни ничего не видел

zolden ★★★★★
()
Ответ на: комментарий от zolden

Ну не гони. Просто те, кто видел, пишут уже довольно редко, большинство с опытом плавно переходят в р/о

GreyDoom ★★★★
()
Ответ на: комментарий от Spoofing

Сейчас покумекал и пришел к выводу такому:

Вынести куски скрипта в функции для простоты.

Сделать отдельную для очистки лока.

Вызывать как-то так

flock -n ${id}.lock {
# тут полезная нагрузка
}
if [ $? -eq 0 ]
then
  rm ${id}.lock
else
  echo ERROR
  exit 4
fi

Получается, что файл лочится на всё время работы полезной нагрузки скрипта, а при повторном запуске flock завершается с ненулевым кодом.

Вроде так.

Radjah ★★★★★
() автор топика

Решение кривое by design
Прозреваю нужен скрипт-диспетчер, который будет контролировать скрипты-исполнители

zolden ★★★★★
()
Ответ на: комментарий от Radjah

В случае flock не надо удалять лок файлы.

anonymous
()
Ответ на: комментарий от Radjah

При работе с flock lock-файлы тебе вообще не нужны:

#!/bin/sh
  exec < "${1}"
  flock 0
  echo locked by ${$}
  sleep 5 # Здесь работаешь с каталогом.
  flock -u 0
  echo unlocked by ${$}
  sleep 2 # Здесь делаешь ещё что-нибудь.
  echo ${$} ended
exit

~ $ for i in 1 2 3 ; do ./tstlocks ~ & done
[1] 23859
[2] 23860
[3] 23861
locked by 23860
locked by 23859
unlocked by 23860
23860 ended
locked by 23861
unlocked by 23859
23859 ended
unlocked by 23861
23861 ended

Если у тебя нет некритической части, разблокировку можно не делать, блокировка снимется сама по завершению скрипта.
Если тебе надо, чтобы налетевший на блокировку скрипт не ждал её освобождения, а завершался, или переходил к другому каталогу, etc..., то тогда нужно использовать опцию -n и проверку кода возврата (только ты почему-то написал бредятину вместо sh-скрипта).
И заметь, что это консультативная (advisory) блокировка, т.е. на реальную возможность работы с каталогом она не влияет.
Можно ещё писать в обрабатываемый каталог lock-файлы UUCP-стиля, как делают pppd или minicom для последовательных портов, но это гораздо костыльней и ненадёжней, и может понадобиться разве что для портируемости на *BSD.

ABW ★★★★★
()
Ответ на: комментарий от intelfx

Вон flock(1) специально придумали, а им всё гонок не хватает в жизни...

в каждой теме про lockfile — появляются советователи «гонок»..

я когда такие темы читаю — мне потом после этого становится страшно использовать софт :-)

user_id_68054 ★★★★★
()
Ответ на: комментарий от ABW

Если у тебя нет некритической части, разблокировку можно не делать, блокировка снимется сама по завершению скрипта.

Главное следить за тем, чтобы дескриптор лок-файла не утёк в дочерние процессы. Хотя в некоторых случаях наоборот именно такое поведение и нужно. В общем надо это учитывать.

Deleted
()
Ответ на: комментарий от ABW

sleep 5 # Здесь работаешь с каталогом.

А что произойдет, если в этом месте скрипт упадет? Аппаратный сбой, допустим. А каталог находится в частично обработанном состоянии. Мы же этого не увидим, а насколько я понял из ОП, это нужно? Будет ли это работать на разных сетевых ФС?

Лор, конечно, крут, продакшен 24х7, вот это все, но можно же просто и бездуховно делать как-то так http://unix.stackexchange.com/a/22047 ? Или нельзя?

Deleted
()
Ответ на: комментарий от ABW

Можно юзать flock на директориях в стиле 9<"$dir"? Офигеть, я думал, что баш не позволяет «перенаправлять» директории...

intelfx ★★★★★
()
Ответ на: комментарий от Deleted

Хорошая идея, но что это даёт по сравнению с вариантом с flock? В обоих случаях нужно защищаться от недообработанных директорий.

Вполне можно создавать в директории (уже находясь под локом), скажем, файл «в обработке» и файл «обработано». И, соответственно, если директория разлочена, а в ней есть только один файл из двух — громко материться.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

что это даёт по сравнению с вариантом с flock

flock это практически линуксизм, в остальных ОС его может не быть. И «flock() does not lock files over NFS». Ну, хорошо, для ОП это можно считать надуманными недостатками.

Но с лок-файлом (совмещенным с pid-файлом) будет же проще? Это же классика: лок-файл на ресурс, пид-файл на процесс, один процесс может лочить несколько ресурсов. Для задачи из ОП их можно объединить, один процесс захватывает один ресурс, каталог.

Факт наличия такого файла - это уже состояние «недообработан», нужно возмущаться. Если пид указывает на несуществующий процесс, значит было незапланированное падение и можно продолжить обрабатывать. Если процесс существует - показать пользователю, пусть разбирается.

Deleted
()
Ответ на: комментарий от ABW

блокировка снимется сама по завершению скрипта.

Даже если kill-ом прибить?

только ты почему-то написал бредятину вместо sh-скрипта

Потому и прошел помощи просить.

Radjah ★★★★★
() автор топика
Ответ на: комментарий от Radjah

Даже если kill-ом прибить?

Да. За это отвечает ядро, а не юзерспейс.

Deleted
()
Ответ на: комментарий от ABW

Потыкал пример по-всякому. Получился вот такой кусок:

# тут переход в нужный каталог, чтобы . указывала на нужное место
exec < .
# блокировка
flock -n 0
# проверка кода возврата
if [ $? -eq 0 ]
then
  # тут полезная нагрузка
  flock -u 0
  echo [*] FINISHED!
else
  echo [!] ERROR! Каталог сохранения уже обрабатывается!
  exit 4
fi

Запускал две копии скрипта, натравленные на один и тот же каталог. Первая работала, вторая ругалась ошибкой из блока else. Скрипты, натравленные на разные каталоги, работают нормально.

Radjah ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.