perl - 使用 Fcntl : Baffling bug involving 'use' and 'require' 锁定文件

标签 perl debugging namespaces locking

以下 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

问题:为什么?

添加:

现在我知道为什么了——谢谢! -- 我想知道处理这个问题的最佳方法是什么:

  1. 只需执行两次use Fcntl,一次在主脚本中,一次在所需的库中(主脚本和库都需要它)。
  2. 将 O_RDONLY 替换为 &O_RDONLY 等。
  3. 将 O_RDONLY 替换为 O_RDONLY() 等。
  4. 还有别的事吗?

最佳答案

通过上述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_RDONLYO_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/

相关文章:

perl - 如何获取草莓perl中最后执行的命令的值

android - android内核调试内存泄漏,addr2line找不到具体地址

perl - cpan 和 cpanm 有什么区别?

regex - Perl 单词拆元音 : removing all vowels except the first and last

node.js - 堆栈跟踪 Nodejs REST API 错误

c++ - 如何避免因 Koenig 查找而导致的标准命名冲突

c# - 具有不同命名空间的 Caliburn Micro ViewLocator

c# - 获取参数的全名(命名空间、类、方法和名称)c#

perl - 为什么我使用 hypnotoad 在 Heroku 上崩溃了?

debugging - Grails 3 设置远程调试ip :port