首先让我展示一下什么是有效的。如果我将 flock 与文件路径一起使用,它就可以工作。
1 号航站楼:
[root@centos ~]# flock -x -n /tmp/foo.txt -c "sleep 100"
2 号航站楼:
[root@centos ~]# flock -x -n /tmp/foo.txt -c "sleep 100"
[root@centos ~]# echo $?
1
上面的输出显示我首先在第一个终端中获取了对/tmp/foo.txt 的独占锁。然后在第二个终端中,当我尝试获取同一文件的锁时,它失败了。
现在让我知道什么不起作用。如果我将 flock 与文件描述符一起使用,它就不起作用。
1 号航站楼:
[root@centos ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt
2 号航站楼:
[root@centos ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt
上面的输出显示,我首先尝试在第一个终端中获取 /tmp/foo.txt
上的锁。然后在第二个终端中,当我尝试获取同一文件的锁时,它成功了。我预计它会像前面的示例一样失败。为什么会成功?
最佳答案
您正在使用 -n
如果无法立即获取锁,它将终止并且 flock
将失败并退出代码 1。因此,在您执行代码后第一个终端,它会休眠 100 秒。接下来,当你在另一个终端执行相同的操作时,flock
失败并返回 1,但是因为有一个 ;
而你没有对返回码做任何事情,shell 简单地继续执行下一条语句并休眠 100 秒。
因此你需要决定flock的返回码如下。
( flock -x -n 100 || exit 55; sleep 100; ) 100> /tmp/foo.txt
现在,如果您在一个终端中执行上述行,它将休眠 100 秒。接下来,如果您在另一个终端上运行代码,它将立即返回提示符。执行 echo $?
,您会看到它已返回 55
,因为我们希望使用 ||
返回。
||
所做的是短路。如果 flock
像正常退出一样返回 0
,这是 shell 的 true 值,它将不会执行表达式的右侧,并且因此转到下一个语句。如果返回值为 1
,这对 shell 来说是一个 false,它将继续计算右边的表达式,即 exit 55
并且因此退出。您也可以通过 if-then-fi
执行此操作。
另请注意,我使用了方括号 ()
而不是大括号 {}
。这是因为,如果您使用大括号,那么命令将在当前 shell 中执行,如果您使用 exit,那么它将从当前 shell 退出。括号将创建一个子 shell,因此从那里执行 exit
会终止子 shell 并返回到原始 shell。
它适用于您使用 -c
的第一个示例,因为您在 flock
参数中包含了单个命令。因此,如果 flock
无法获取锁,它就不会执行语句并终止。
关于linux - 无法使用带有文件描述符的群来锁定文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30658145/