以下 Perl 脚本如您所料输出“SUCCESS”:
use Fcntl qw(:DEFAULT :flock);
sysopen(LF, "test.txt", O_RDONLY | O_CREAT) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX)) { print "SUCCESS.\n"; }
else { print "FAIL: $!\n"; }
但是现在,将第一行替换为
require "testlib.pl";
其中 teSTLib.pl 包含
use Fcntl qw(:DEFAULT :flock);
1;
现在,奇怪的是,脚本失败了,如下所示:
FAIL: Bad file descriptor
问题:为什么?
添加:
现在我知道为什么了——谢谢! -- 我想知道处理这个问题的最佳方法是什么:
- 只需执行两次
use Fcntl
,一次在主脚本中,一次在所需的库中(主脚本和库都需要它)。 - 将 O_RDONLY 替换为 &O_RDONLY 等。
- 将 O_RDONLY 替换为 O_RDONLY() 等。
- 还有别的事吗?
最佳答案
通过上述use
,您剥夺了 Perl 解析器 O_RDONLY
等人的知识。是无参数子程序。在这种情况下你必须更详细一点:
sysopen(LF, "test.txt", O_RDONLY() | O_CREAT()) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX())) { print "SUCCESS.\n"; }
编辑:为了进一步详细说明,如果没有括号,O_RDONLY
和 O_CREAT
会被解释为裸字(字符串),其行为与您不同。 d 期望当二进制或在一起时:
$ perl -le 'print O_RDONLY | O_CREAT'
O_SVOO\Y
(各个字符按位或运算在一起。)
在这种情况下,字符串“O_SVOO\Y”(或系统上的任何内容)被解释为 sysopen
的数字 0,因此只要 O_RDONLY
为 0(这是典型的情况)并且文件已经存在(因此 O_CREAT
是多余的)。但 fcntl 显然对非数字参数不那么宽容:
$ perl -e 'flock STDOUT, "LOCK_EX" or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.
同样:
$ perl -e 'flock STDOUT, LOCK_EX or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.
但是:
$ perl -e 'use Fcntl qw(:flock); flock STDOUT, LOCK_EX or die "Failed: $!"'
(no output)
最后,请注意,use strict
提供了许多有用的线索。
关于perl - 使用 Fcntl : Baffling bug involving 'use' and 'require' 锁定文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3175568/