bash 中的独占锁和共享锁
Exclusive and shared locks in bash
我正在尝试使用 bash 锁定一个文件,我已经设法做到了,但我不确定我的做法是否正确。
下面的代码应该尝试写入 lock.log
文件,如果失败,它应该以退出状态 -1 退出。如果它可以锁定文件,那么它应该打印订单号,解锁文件,然后退出。
#!/bin/bash
function myfunc {
(
flock -e -n 200 || { echo " - can't reach"; exit -1; }
echo >> #critical
sleep 2
flock -u 200
) 200> #critical
echo " -> end."
exit 0
}
lock="lock.log"
for ((i=0; i < 10; i++)); do
myfunc $i $lock &
done
exit 0
我不明白为什么它会打印在标准输出上,并且标记为关键的 2 行对我来说不是很清楚,所以我恳请您提供一些解释,也许还有一个更好的例子。
可能会有一些类似的问题,但是 none 我要问的基本问题 - flock
的用法
谢谢
让我们从 200>""
部分开始:
当 myfunc
被调用时 Bash 看到这个:
(
... stuff irrelevant for now ...
) 200>""
因此它打开文件描述符编号 200 并将其重定向到通过扩展 </code> 获得的文件。在你的情况下,它完全像:</p>
<pre><code>(
... 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
。
我想这解释了 critical 行之一。
现在 subshell 内部发生了什么?我不是 flock
专家,请耐心等待。
使用参数 200
,您告诉 flock
使用文件描述符 200
(即“文件”/dev/fd/200
)作为锁定文件.当您调用 flock 200
时,flock
会尝试保留该文件。如果可以,一切都很好,它会一直掌握它,否则它要么失败(如果给定 -n
选项,这是你的情况),要么等到其他人放开文件。
万一失败,你输出 can't reach 消息 到标准输出 并退出 subshell,然后您正在执行函数的剩余部分(即消息 end)。现在,如果成功,您将 echo
传递给函数的第一个参数(这里是一个数字)并将其重定向到文件 lock.log
。这是否解释了第二个 critical 行?
在此脚本结束时,您会看到文件 lock.log
是空的。那是因为对 myfunc 的第一次调用成功了,但所有后续调用都会截断文件 lock.log
(跟你一起响铃?)。如果您想查看 lock.log
中的某些内容,请只调用您的函数一次(以便后续调用不会截断文件),或者以追加模式打开文件:
(
... the flock stuff ...
) 200>>"" # notice the >> instead of >
这样你会看到第一个成功的锁(不一定是数字 0
,因为存在竞争条件)。
我正在尝试使用 bash 锁定一个文件,我已经设法做到了,但我不确定我的做法是否正确。
下面的代码应该尝试写入 lock.log
文件,如果失败,它应该以退出状态 -1 退出。如果它可以锁定文件,那么它应该打印订单号,解锁文件,然后退出。
#!/bin/bash
function myfunc {
(
flock -e -n 200 || { echo " - can't reach"; exit -1; }
echo >> #critical
sleep 2
flock -u 200
) 200> #critical
echo " -> end."
exit 0
}
lock="lock.log"
for ((i=0; i < 10; i++)); do
myfunc $i $lock &
done
exit 0
我不明白为什么它会打印在标准输出上,并且标记为关键的 2 行对我来说不是很清楚,所以我恳请您提供一些解释,也许还有一个更好的例子。
可能会有一些类似的问题,但是 none 我要问的基本问题 - flock
谢谢
让我们从 200>""
部分开始:
当 myfunc
被调用时 Bash 看到这个:
(
... stuff irrelevant for now ...
) 200>""
因此它打开文件描述符编号 200 并将其重定向到通过扩展 </code> 获得的文件。在你的情况下,它完全像:</p>
<pre><code>(
... 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
。
我想这解释了 critical 行之一。
现在 subshell 内部发生了什么?我不是 flock
专家,请耐心等待。
使用参数 200
,您告诉 flock
使用文件描述符 200
(即“文件”/dev/fd/200
)作为锁定文件.当您调用 flock 200
时,flock
会尝试保留该文件。如果可以,一切都很好,它会一直掌握它,否则它要么失败(如果给定 -n
选项,这是你的情况),要么等到其他人放开文件。
万一失败,你输出 can't reach 消息 到标准输出 并退出 subshell,然后您正在执行函数的剩余部分(即消息 end)。现在,如果成功,您将 echo
传递给函数的第一个参数(这里是一个数字)并将其重定向到文件 lock.log
。这是否解释了第二个 critical 行?
在此脚本结束时,您会看到文件 lock.log
是空的。那是因为对 myfunc 的第一次调用成功了,但所有后续调用都会截断文件 lock.log
(跟你一起响铃?)。如果您想查看 lock.log
中的某些内容,请只调用您的函数一次(以便后续调用不会截断文件),或者以追加模式打开文件:
(
... the flock stuff ...
) 200>>"" # notice the >> instead of >
这样你会看到第一个成功的锁(不一定是数字 0
,因为存在竞争条件)。