Использование каталога блокировки:
#!/bin/sh
lockdir=${TMPDIR:-/tmp}/mylock
if ! mkdir "$lockdir" 2>/dev/null; then
exit 1
fi
trap 'rmdir "$lockdir" 2>/dev/null' EXIT HUP INT TERM
# The rest of code goes here.
Использование каталога блокировки безопаснее, чем использование файла блокировки. Если вы используете файл, вам нужно будет выполнить отдельную проверку существования файла перед его созданием. В промежутке между этими двумя операциями другой экземпляр скрипта может попытаться сделать то же самое. Утилита mkdir
предоставляет атомарную операцию «создать -, если -не -существует».
Предупреждение :Приведенный выше код не определяет, запущен ли сценарий, а определяет, существует ли каталог блокировки. Если скрипт завершается ненормально, например. после уничтожения с помощью SIGKILL
каталог блокировки останется позади, и никакие новые экземпляры скрипта не смогут запуститься.
Следующий вариант пытается обнаружить каталог блокировки, оставленный аварийно завершенным сценарием. Он только обнаруживает левую -чрезмерную блокировку, но не пытается выполнить какую-либо очистку (это приведет к новым условиям гонки -).
#!/bin/sh
lockdir=${TMPDIR:-/tmp}/mylock
if { read pid <"$lockdir/pid" && ! kill -0 "$pid"; } 2>/dev/null then
printf 'Detected left-over lock "%s"\n' "$lockdir" >&2
exit 1
fi
if ! mkdir "$lockdir" 2>/dev/null; then
echo 'Could not get lock' >&2
exit 1
fi
printf '%d\n' "$$" >"$lockdir/pid"
trap '{ rm "$lockdir/pid" && rmdir "$lockdir"; } 2>/dev/null' EXIT HUP INT TERM
# The rest of code goes here.
Команда ! kill -0 "$pid"
будет истинной, если $pid
не относится к идентификатору процесса, который в настоящее время выделен для запущенного процесса.
Я выяснил, для чего были созданы эти файлы. У меня был процесс, работающий в контейнере (с монтированием ядра Linux (файловой системой )пространством имен ), созданным Firejail . Firejail маскирует некоторые файлы (, например. исполняемые файлы и библиотеки )от доступа к процессу внутри контейнера. Таким образом, на эти файлы по-прежнему ссылается ядро Linux, когда они удаляются с помощью yum update
/ dnf update
. Следовательно, они не удаляются в то время.
Это также означает, что файлы могут быть безопасно удалены после перезагрузки -или даже после закрытия последнего процесса-контейнера, использующего их.
Остается вопрос, почему эти файлы не удаляются при выключении контейнера/компьютера. Я подозреваю, что это ошибка, не исправленная в драйвере файловой системы ядра (ext4? )на этих машинах.