为啥 Perl 的两个 arg open 似乎去掉了换行符?
Posted
技术标签:
【中文标题】为啥 Perl 的两个 arg open 似乎去掉了换行符?【英文标题】: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)。
【问题讨论】:
【参考方案1】:perldoc perlopentut:
另一个需要注意的重要事情是,就像在 shell 中一样,文件名之前或之后的任何空格都会被忽略。这很好,因为您不希望它们做不同的事情:
open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"
这不是错误,而是一项功能。因为open 以使用重定向箭头来指定如何打开文件的方式模仿shell,所以它也会在文件名本身周围的额外空格方面这样做。要访问具有顽皮名称的文件,请参阅Dispelling the Dweomer。
还有一个 3 参数版本的 open,它可以让您将特殊的重定向字符放入它们自己的参数中:
…
在这种情况下,要打开的文件名是
$datafile
中的实际字符串,因此您不必担心$datafile
包含可能影响打开模式的字符,或者文件名开头的空格将被吸收在 2 参数版本中。此外,减少不必要的字符串插值是一件好事。
【讨论】:
这是 3-argopen
的优势之一。
这是 3-arg open
的缺点之一 ;-)【参考方案2】:
这很简单:因为 2-arg open
的语法类似于 shell 的语法,甚至可以使用管道。
【讨论】:
也许如果open
和sysopen
分别被称为shell_open
和C_open
,人们可能会更快地掌握他们的本性。好吧,20年前的人们;没有人知道那些恐龙语言了。
@tchrist,哦,我真希望system
被这样拆分(shell($shell_cmd)
-vs- system($prog, @opt_args)
)以上是关于为啥 Perl 的两个 arg open 似乎去掉了换行符?的主要内容,如果未能解决你的问题,请参考以下文章