Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 防止锁传播_Bash_Locking_File Descriptor - Fatal编程技术网

Bash 防止锁传播

Bash 防止锁传播,bash,locking,file-descriptor,Bash,Locking,File Descriptor,在bash下执行锁定的一种简单且看似可靠的方法是: exec 9>>lockfile flock 9 然而,众所周知,bash将这种fd锁传播到所有分叉的东西,包括执行的程序等 有没有办法告诉bash不要复制fd?锁被附加到fd上是很好的,当程序终止时,fd会被移除,不管它是如何终止的 我知道我可以做一些事情,比如: run_some_prog 9>&- 但这相当乏味 有更好的解决方案吗?在bash中没有办法将FD标记为close on exec,因此没有更好的解决

在bash下执行锁定的一种简单且看似可靠的方法是:

exec 9>>lockfile
flock 9
然而,众所周知,bash将这种fd锁传播到所有分叉的东西,包括执行的程序等

有没有办法告诉bash不要复制fd?锁被附加到fd上是很好的,当程序终止时,fd会被移除,不管它是如何终止的

我知道我可以做一些事情,比如:

run_some_prog 9>&-
但这相当乏味


有更好的解决方案吗?

在bash中没有办法将FD标记为close on exec,因此没有更好的解决方案。

您可以使用
-o
命令行选项来
flock(1)
(长选项
--close
,这可能更适合在脚本中编写自文档性质的代码)要指定在通过
flock(1)
执行命令之前应关闭文件描述符,请执行以下操作:


-o
不适用于文件描述符,它只适用于文件。您必须使用
-u
解锁文件描述符

我所做的是:

# start of the lock sections
LOCKFILE=/tmp/somelockfile
exec 8>"$LOCKFILE"
if ! flock -n 8;then
      echo Rejected  # for testing, remove this later
      exit           # exit, since we don't have lock
fi

# some code which shouldn't run in parallel

# End of lock section
flock -u 8
rm -f "$LOCKFILE"

通过这种方式,文件描述符将被锁定的进程关闭,并且由于每个其他进程都将退出,这意味着只有持有锁的进程才会解锁文件描述符并删除锁定文件。

显然
flock-o FD
无法解决此问题。对于同一shell脚本中的后续命令,消除多余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
写得好一点,保持自然的命令流,代价是另一个fork加上一个额外的流程和一点不同的工作流,这通常很方便但这不允许在外壳中设置变量

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
var=外部
exec 9>>锁文件
鸥群-n 9 | |出口
(

exec 9Thx!正是我想要的。不适用于
flock 9
,这仅适用于
flock-o lockfile命令[args..]
情况
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