Видимо flock -o FD
не решает проблему. Уловка, чтобы избавиться от лишнего FD для более поздних команд в том же самом сценарии оболочки, состоит в том, чтобы обернуть оставшуюся часть в раздел, который закрывает FD, как это:
var=outside
exec 9>>lockfile
flock -n 9 || exit
{
: commands which do not see FD9
var=exported
# exit would exit script
# see CLUMSY below outside this code snippet
} 9<&-
# $var is "exported"
# drop lock closing the FD
exec 9<&-
: remaining commands without lock
Это бит CLUMSY
, потому что закрытие FD так далеко отделено от блокировки.
Вы можете изменить это, потеряв «естественный» поток команд, но собрав вместе вещи, которые принадлежат друг другу:
functions_running_with_lock()
{
: commands which do not see FD9
var=exported
# exit would exit script
}
var=outside
exec 9>>lockfile
flock -n 9 || exit
functions_running_with_lock 9<&-
# $var is "exported"
# drop lock closing the FD
exec 9<&-
: remaining commands without lock
Небольшое более приятное написание, которое поддерживает естественный поток команд за счет другого форка, плюс дополнительный процесс и немного другой рабочий процесс, что часто бывает удобно. Но это не позволяет устанавливать переменные во внешней оболочке :
var=outside
exec 9>>lockfile
flock -n 9 || exit
(
exec 9<&-
: commands which do not see FD9
var=exported
# exit does not interrupt the whole script
exit
var=neverreached
)
# optionally test the ret if the parentheses using $?
# $var is "outside" again
# drop lock closing the FD
exec 9<&-
: remaining commands without lock
Кстати, если вы действительно хотите быть уверены, что bash
не вводит дополнительные файловые дескрипторы (чтобы «спрятать» закрытый FD и пропустить реальный форк), например, если вы выполняете какой-то демон, который затем удерживает блокировку навсегда, последний вариант рекомендуется, просто чтобы быть уверенным. lsof -nP
и strace your_script
ваши друзья.