我正在尝试使用bash锁定文件,而我已设法这样做,但我不确定我是否正确地执行此操作。
下面的代码应该尝试写入lock.log
文件,如果失败则应退出退出状态-1。如果它可以锁定文件,那么它应该打印订单号,解锁文件,然后退出。
#!/bin/bash
function myfunc {
(
flock -e -n 200 || { echo "$1 - can't reach"; exit -1; }
echo $1 >> $2 #critical
sleep 2
flock -u 200
) 200>$2 #critical
echo "$1 -> end."
exit 0
}
lock="lock.log"
for ((i=0; i < 10; i++)); do
myfunc $i $lock &
done
exit 0
我无法理解为什么它会在标准输出上打印而且标记为关键的2行对我来说不太清楚,所以我请求一些解释,也许是为了更好的例子。
可能存在一些类似的问题,但没有一个问题与我提出的基本问题有关 - flock
的使用
谢谢
答案 0 :(得分:2)
让我们从200>"$2"
部分开始:
当调用myfunc
时,Bash会看到:
(
... stuff irrelevant for now ...
) 200>"$2"
因此它打开文件描述符号200并将其重定向到通过扩展$2
获得的文件。在你的情况下,它就像:
(
... stuff irrelevant for now ...
) 200>lock.log
顺便说一下,文件lock.log
此时已打开并被截断(即,其内容(如果有的话)被清除)。
要查看此内容,请尝试以下操作:
( ls /dev/fd ) 200>lock.log
你会看到那里有一个名为200
的“文件”(此时,请使用包含某些内容的lock.log
文件进行尝试,之后您会看到它内容消失了)但与
ls /dev/fd
您很可能只看到0
,1
,2
,3
。为了好玩,试试:
( ls /dev/fd >&200 ) 200>lock.log
这次终端屏幕上没有显示任何内容,但您会看到ls
的内容位于文件lock.log
中(包含之前的内容,如果有的话,已删除)。这是因为我们使用>&200
将ls
的标准输出重定向到200
的文件描述符/dev/fd/200
,然后将其重定向到文件lock.log
。
我想这解释了其中一条关键行。
现在子shell内发生了什么?我不是flock
专家,所以请耐心等待。
使用参数200
,您告诉flock
使用文件描述符200
(即“文件”/dev/fd/200
)作为锁定文件。当您致电flock 200
时,flock
会尝试暂停该文件。如果它可以,一切都很好,它会抓住它,否则它会失败(如果给出-n
选项,这是你的情况)或等到其他人让文件进入。
如果失败,您将输出无法到达消息到标准输出并退出子shell,然后您正在执行其余部分功能(即消息 end )。现在,如果成功,你echo
传递给函数的第一个参数(这里是一个数字),你将它重定向到文件lock.log
。这是否解释了第二个关键行?
在此脚本的末尾,您会看到文件lock.log
为空。那是因为第一次调用myfunc成功,但所有后续调用都会截断文件lock.log
(和你一起响铃?)。如果你想在lock.log
中看到一些内容,要么只调用你的函数一次(以便后续调用没有截断文件),要么以追加模式打开文件:
(
... the flock stuff ...
) 200>>"$2" # notice the >> instead of >
就像这样你会看到成功的第一个锁(不一定是数字0
,因为有竞争条件)。