【问题标题】:Why does Perl's two arg open seem to strip newlines?为什么 Perl 的两个 arg open 似乎去掉了换行符?
【发布时间】:2012-06-28 21:52:00
【问题描述】:

当我使用包含尾随换行符的文件名调用 perl 的两个参数 open() 时,将忽略换行符。但是,三参数版本保留了换行符。

为什么行为不同?为什么换行符表面上被剥离了?

-- 文件“nl”不存在。实现它

$ ls -1 nl;触摸 nl; ls -1 nl
ls: nl: 没有这样的文件或目录
nl

-- 尝试三参数打开 "nl\n" → ENOENT

strace 显示了我期望的行为,FWIW。

$ perl -E 'open(F, "&1 | grep nl
open("nl\n", O_RDONLY|O_LARGEFILE) = -1 ENOENT (没有那个文件或目录)

-- 现在,试试双参数 open "nl\n" → 成功?

$ perl -E 'open(F, "nl\n") or die $!'

-- 什么?为什么这行得通?我们来看看 strace。

哦,它忽略了换行符:

$ strace -e trace=open perl -E 'open(F, "nl\n") or die $!' 2>&1 | grep nl
open("nl", O_RDONLY|O_LARGEFILE) = 3

-- "nl" 仍然是唯一的文件

$ ls
nl

背景:

$ perl -v

这是为 i686-linux-thread-multi 构建的 perl 5,版本 16,subversion 0 (v5.16.0)。

【问题讨论】:

    标签: perl filesystems


    【解决方案1】:

    perldoc perlopentut:

    另一个需要注意的重要事情是,就像在 shell 中一样,文件名之前或之后的任何空格都会被忽略。这很好,因为您不希望它们做不同的事情:

    open INFO, "<datafile"
    open INFO, "< datafile"
    open INFO, "< datafile"
    

    这不是错误,而是一项功能。因为open 以使用重定向箭头来指定如何打开文件的方式模仿shell,所以它也会在文件名本身周围的额外空格方面这样做。要访问具有顽皮名称的文件,请参阅Dispelling the Dweomer

    还有一个 3 参数版本的 open,它可以让您将特殊的重定向字符放入它们自己的参数中:

    在这种情况下,要打开的文件名是 $datafile 中的实际字符串,因此您不必担心 $datafile 包含可能影响打开模式的字符,或者文件名开头的空格将被吸收在 2 参数版本中。此外,减少不必要的字符串插值是一件好事。

    【讨论】:

    • 这是 3-arg open 的优势之一。
    • 这是 3-arg open 的缺点之一 ;-)
    【解决方案2】:

    这很简单:因为 2-arg open 的语法类似于 shell 的语法,甚至可以使用管道。

    【讨论】:

    • 也许如果opensysopen 分别被称为shell_openC_open,人们可能会更快地掌握他们的本性。好吧,20年前的人们;没有人知道那些恐龙语言了。
    • @tchrist,哦,我真希望system 被这样拆分(shell($shell_cmd) -vs- system($prog, @opt_args)
    猜你喜欢
    • 2012-02-01
    • 1970-01-01
    • 2010-11-13
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多