Mr.*_*esh 8 file-descriptors subshell flock
我最近一直在尝试为一个小项目创建一个 shell 脚本,但由于某种原因,该flock
命令对我不起作用。每当我在子 shell 中以原子方式调用它并将其置于后台时,其他程序似乎能够读取/写入锁定的文件。
Bash 会话:
guest@guest ~ $ touch ./temp
guest@guest ~ $ ( flock -x 3 && sleep 99999999999; ) 3>./temp &
[1] 22874
guest@guest ~ $ cat ./temp
guest@guest ~ $ echo this is a test >./temp
guest@guest ~ $ cat ./temp
this is a test
guest@guest ~ $ jobs
[1]+ Running ( flock -x 3 && sleep 99999999999 ) 3>./temp &
guest@guest ~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Run Code Online (Sandbox Code Playgroud)
我觉得我可能遗漏了一些与“flock”程序内部相关的非常简单的东西,但不知道它可能是什么。
Kus*_*nda 10
flock
进行咨询锁定,这是一种协作锁定方案。这意味着如果您不合作,您将能够覆盖锁定。您通过在执行操作之前请求锁定来合作,然后在完成后释放锁定。这是受锁定保护的操作,而不是(必须)锁定文件本身。
从我的系统上的flock(2)
手册:
咨询锁允许协作进程对文件执行一致的操作,但不保证一致性(即,进程仍可在不使用咨询锁的情况下访问文件,这可能会导致不一致)。
考虑这个脚本:
#!/bin/sh
( flock -x 9 || exit 1
echo '1: Locking for 5 secs'; sleep 5; echo '1: Done' ) 9>/tmp/lock &
sleep 1
echo '2: Will now attempt to get lock'
( flock -x 9 || exit 1
echo '2: Got lock' ) 9>/tmp/lock
# Since the second flock call only performs one operation, the whole last
# subshell may be replaced by just
# flock -x /tmp/lock -c echo '2: Got lock'
#
# (-x and -c are not needed, a lock is exclusive ("write lock")
# unless -s is used to create a shared lock ("read lock"),
# and the -c is optional)
Run Code Online (Sandbox Code Playgroud)
输出:
1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock
Run Code Online (Sandbox Code Playgroud)
您可以看到该锁是由后台进程获取的,并且其他flock
调用必须等待它被释放才能锁定它。
还要注意,锁定文件不是这里受保护的,而是echo
子shell 中的操作保证是独占的。特别是,锁定文件不受写入或读取它的不合作进程的保护。
这意味着,每个flock
子外壳,通过锁定/tmp/lock
在这个例子中,保证了操作(上的文件或其他共享数据资源)将不会与冲突操作从混杂任何其他程序使用flock
与/tmp/lock
作为锁定文件。
为了说明上面的最后一段,在两个不同的终端(可能稍微增加睡眠时间)中运行我上面的脚本,尽可能同时,并验证两个相互竞争的脚本是否适当地获取了锁(相互等待)。由于在后台进程中请求了一个锁,这意味着在同时运行脚本的两个实例时,可能会按照脚本中指定的顺序获取锁。
在您的示例中,交互式 shell不与锁定机制合作。这就是为什么即使锁定由后台子shell 持有,您也可以读取和写入文件的原因。
另请注意,并非所有文件系统都支持文件锁定flock
(或其等效的 C 库,flock()
)。例如,网络文件系统 AFS 和 NFS 在这方面可能存在问题。请参阅https://en.wikipedia.org/wiki/File_locking#Problems
归档时间: |
|
查看次数: |
8332 次 |
最近记录: |