为什么Perl的两个arg开放似乎剥离换行?

pil*_*row 6 filesystems perl

当我open()使用包含尾随换行符的文件名调用perl的two-arg 时,将忽略换行符.然而,三个arg版本保留了换行符.

为什么行为会有所不同?为什么新线表面上被剥离了?

- 文件"nl"不存在.做了

$ ls -1 nl; touch nl; ls -1 nl
ls: nl: No such file or directory
nl

- 尝试三个arg打开"nl \n"→ENOENT

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

$ perl -E 'open(F, "<", "nl\n") or die $!'
No such file or directory at -e line 1.

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

- 现在,试试两个arg打开"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,颠覆0(v5.16.0).

Sin*_*nür 11

perldoc perlopentut:

另一个需要注意的重要事项是,就像在shell中一样,忽略文件名之前或之后的任何空格.这很好,因为你不希望这些做不同的事情:

open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"
Run Code Online (Sandbox Code Playgroud)

这不是一个错误,而是一个功能.因为open以其使用重定向箭头的方式模仿shell来指定如何打开文件,所以它也是关于文件名本身周围的额外空格.要访问具有顽皮名称的文件,请参阅消除Dweomer.

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

...

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

  • 这是3-arg`open`的优势之一. (2认同)