无法用文件描述符locking文件

首先让我表明什么是有效的。 如果我使用文件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.txtlocking。 然后在第二个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无法获得锁定,它将不会执行该语句并终止。