当我使用包含尾随换行符的文件名调用perl的两个arg open()
时,将忽略换行符。然而,three-arg版本保留了换行符。
为什么行为有所不同?为什么新线表面上被剥离了?
$ ls -1 nl; touch nl; ls -1 nl ls: nl: No such file or directory nl
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)
$ perl -E 'open(F, "nl\n") or die $!'
哦,它忽略了换行符:
$ strace -e trace=open perl -E 'open(F, "nl\n") or die $!' 2>&1 | grep nl open("nl", O_RDONLY|O_LARGEFILE) = 3
$ ls nl
背景:
$ perl -v
这是为i686-linux-thread-multi构建的perl 5,版本16,颠覆0(v5.16.0)。
答案 0 :(得分:11)
另一个需要注意的重要事项是,就像在shell中一样,忽略文件名之前或之后的任何空格。这很好,因为你不希望这些做不同的事情:
open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"
这不是一个错误,而是一个功能。因为open模仿shell使用重定向箭头指定如何打开文件的样式,所以它也是关于文件名本身周围的额外空格。要访问具有顽皮名称的文件,请参阅Dispelling the Dweomer。
还有一个3参数版本的open,它允许你将特殊的重定向字符放入它们自己的参数中:
...
在这种情况下,要打开的文件名是
$datafile
中的实际字符串,因此您不必担心$datafile
包含可能影响打开模式的字符,或者开头的空格将在2参数版本中吸收的文件名。此外,减少不必要的字符串插值是一件好事。
答案 1 :(得分:2)
这很简单:因为2-arg open
的语法近似于shell,即使是允许管道。