首先让我表明什么是有效的。 如果我使用文件path,它可以工作。
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
上面的输出显示我第一次在第一个terminal上获得对/tmp/foo.txt的独占锁。 然后在第二个terminal,当我尝试获取同一个文件的锁时,它失败了。
现在让我知道什么是行不通的。 如果我使用文件描述符群,它不起作用。
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
以上输出显示我首先尝试在第一个terminal上获取/tmp/foo.txt
locking。 然后在第二个terminal上,当我试图获得对同一个文件的locking时,它成功了。 我预料它会像前面的例子那样失败。 为什么成功?
你正在使用-n
,如果不能立刻获得锁,那么flock
将会退出,退出代码1将失败。因此,在第一个终端中执行你的代码后,睡眠100秒。 接下来,当你在另一个终端执行同样的操作时, flock
失败并返回1,但是因为有一个;
而且你对返回代码没有做任何事情,shell只是继续执行下一个语句,睡100秒。
因此,您需要按照以下方式决定鸡群的返回码。
( flock -x -n 100 || exit 55; sleep 100; ) 100> /tmp/foo.txt
现在,如果你在一个终端上面执行上面的行,它将会睡100秒。 接下来,如果您在另一个终端上运行代码,它将立即返回到提示。 做一个echo $?
你会看到它返回了55
因为我们想用||
返回 。
什么||
确实是短路。 如果flock
返回0
如同在shell中的真正值的正常退出一样,它不会执行表达式的右边,因此转到下一个语句。 如果返回值是1
,这对于shell是错误的,它将继续计算exit 55
的右侧表达式,因此退出。 你也可以通过if-then-fi
来做到这一点。
另请注意,我使用了括号()
而不是大括号{}
。 这是因为,如果使用curley-braces,则命令将在当前shell中执行,如果使用exit,则会从当前shell中退出。 括号将创建一个子shell,因此从那里exit
终止子shell并将其返回到您的原始shell。
它为你的第一个例子使用-c
因为你有在flock
参数内的单个命令。 因此,如果flock
无法获得锁定,它将不会执行该语句并终止。