Bash flock: выход, если не удается получить блокировку

Следующий механизм блокировки используется для предотвращения одновременного запуска задания cron:

#!/bin/bash

echo "Before critical section"
(
    flock -e 200
    echo "In critical section"
    sleep 5
) 200>/tmp/blah.lockfile
echo "After critical section"

При одновременном запуске двух экземпляров последний ждет, пока первый не закончит, а затем запустится. Это может привести к отставанию ожидающих запуска журналов.

Как мне изменить этот script, чтобы, если flock не может получить блокировку, он завершает script? Я пробовал -n без успеха.

Ответ 1

flock -n -e 200 || exit 1

flock -n сообщает вам об ошибке, возвращая код сбоя (что-то отличное от нуля). Вместо этого вы можете сделать set -e в верхней части вашего script, чтобы он выходил, когда он видит любую непроверенную ошибку.

В зависимости от вашего приложения вам может понадобиться exit 0, чтобы указать успех, когда блокировка не может быть получена.

Ответ 2

Мы используем эксклюзивную блокировку самого файла script, $0 - это имя командного файла.

exec 200<$0
flock -n 200 || exit 1

Все решение состоит из двух строк кода. Но фокус в том, чтобы открыть $0 для чтения, а затем получить для него эксклюзивный замок.