通常建议不要在Perl代码中使用其他Linux工具; 例如,如果有人打算打印文本文件的最后一行,他可以:
$last_line = `tail -1 $file` ;
或以其他方式,打开文件并逐行阅读
open(INFO,$file);
while(<INFO>) {
$last_line = $_ if eof;
}
使用上一个版本有什么缺陷,为什么我应该避免在我的代码中使用shell工具?
感谢名单,
答案 0 :(得分:24)
答案 1 :(得分:15)
最好将所有操作保留在Perl中,因为它更快,因为它更安全。它更快,因为你没有产生一个新进程,而且它更安全,因为你不必担心shell元字符欺骗。
例如,在您的第一种情况下$file
包含“afilename ; rm -rf ~
”,您将是一个非常不开心的露营者。
P.S。做尾巴的最好的全部Perlway是使用File::ReadBackwards
答案 2 :(得分:10)
不执行shell命令的一个主要原因(除了可移植性)是它通过生成另一个进程来引入开销。这就是Perl模块中通过CPAN提供大部分相同功能的原因。
答案 3 :(得分:9)
一个原因是您的Perl代码可能在没有名为“tail”的shell工具的环境中运行。
这取决于项目,这是个人电话:
答案 4 :(得分:5)
使用tail
?精细。但这确实是一个特例,因为它很容易使用,因为它非常简单。
问题一般不是效率或可移植性,这在很大程度上是无关紧要的;问题是易用性。要运行外部实用程序,您必须找出它接受的参数,编写代码以将程序的数据结构转换为该格式,正确引用它们,构建命令行并运行应用程序。然后,您可能必须提供数据并从中读取数据(涉及事件循环等复杂性,担心死锁等),最后解释返回值。 (UNIX进程认为“0”为真,其他任何都是假的,但Perl假定相反。foo() and die
很难阅读。)这是很多工作要做,这就是人们避免它的原因。创建类的实例并在其上调用方法以获取所需的数据要容易得多。
(您可以通过这种方式抽象出过程;例如,请参阅Crypt :: GpgME。它处理与调用gpg
相关的复杂性,这通常涉及创建除STDOUT,STDIN和STDERR之外的多个文件句柄,其他的东西。)
答案 5 :(得分:4)
我认为在Perl中完成所有这一切的主要原因是坚固性。如果文件名具有shell元字符或空格,或者不存在或无法访问,则使用tail将失败。从Perl中,文件名中的字符不是问题,您可以区分访问文件时的错误。有时候,健壮是比快速编码更重要的,有时候不是。