为什么我不应该在Perl代码中使用shell工具?

时间:2009-07-25 19:03:37

标签: perl

通常建议不要在Perl代码中使用其他Linux工具; 例如,如果有人打算打印文本文件的最后一行,他可以:

$last_line = `tail -1 $file` ;

或以其他方式,打开文件并逐行阅读

 open(INFO,$file);
 while(<INFO>) {
   $last_line = $_ if eof;
   }

使用上一个版本有什么缺陷,为什么我应该避免在我的代码中使用shell工具?

感谢名单,

6 个答案:

答案 0 :(得分:24)

  • 效率 - 您不必生成新流程
  • 可移植性 - 您不必担心可执行文件不存在,接受不同的交换机或具有不同的输出
  • 易于使用 - 您不必解析输出,结果已经是可用的形式
  • 错误处理 - 您可以更好地控制错误以及在Perl中如何处理错误。

答案 1 :(得分:15)

最好将所有操作保留在Perl中,因为它更快,因为它更安全。它更快,因为你没有产生一个新进程,而且它更安全,因为你不必担心shell元字符欺骗。

例如,在您的第一种情况下$file包含“afilename ; rm -rf ~”,您将是一个非常不开心的露营者。

P.S。做尾巴的最好的全部Perlway是使用File::ReadBackwards

答案 2 :(得分:10)

不执行shell命令的一个主要原因(除了可移植性)是它通过生成另一个进程来引入开销。这就是Perl模块中通过CPAN提供大部分相同功能的原因。

答案 3 :(得分:9)

一个原因是您的Perl代码可能在没有名为“tail”的shell工具的环境中运行。

这取决于项目,这是个人电话:

  • 是否总是在带有尾部的shell环境中使用?
  • 您是否只关心使用纯Perl代码?

答案 4 :(得分:5)

使用tail?精细。但这确实是一个特例,因为它很容易使用,因为它非常简单。

问题一般不是效率或可移植性,这在很大程度上是无关紧要的;问题是易用性。要运行外部实用程序,您必须找出它接受的参数,编写代码以将程序的数据结构转换为该格式,正确引用它们,构建命令行并运行应用程序。然后,您可能必须提供数据并从中读取数据(涉及事件循环等复杂性,担心死锁等),最后解释返回值。 (UNIX进程认为“0”为真,其他任何都是假的,但Perl假定相反。foo() and die很难阅读。)这是很多工作要做,这就是人们避免它的原因。创建类的实例并在其上调用方法以获取所需的数据要容易得多。

(您可以通过这种方式抽象出过程;例如,请参阅Crypt :: GpgME。它处理与调用gpg相关的复杂性,这通常涉及创建除STDOUT,STDIN和STDERR之外的多个文件句柄,其他的东西。)

答案 5 :(得分:4)

我认为在Perl中完成所有这一切的主要原因是坚固性。如果文件名具有shell元字符或空格,或者不存在或无法访问,则使用tail将失败。从Perl中,文件名中的字符不是问题,您可以区分访问文件时的错误。有时候,健壮是比快速编码更重要的,有时候不是。