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

sud*_*03r 4 perl

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

$last_line = `tail -1 $file` ;
Run Code Online (Sandbox Code Playgroud)

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

 open(INFO,$file);
 while(<INFO>) {
   $last_line = $_ if eof;
   }
Run Code Online (Sandbox Code Playgroud)

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

感谢名单,

Cha*_*ens 24

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


Ry4*_*ase 15

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

例如,在你的第一个案例中如果$file包含" afilename ; rm -rf ~",那么你将是一个非常不开心的露营者.

PS做尾巴的最好的全部Perlway是使用File :: ReadBackwards


enn*_*ler 10

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


the*_*edz 9

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

根据项目,这是个人电话:

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


jro*_*way 5

tail?精细.但这确实是一个特例,因为它很容易使用,因为它是如此微不足道.

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

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

  • 我能理解,如果你想,"嘿,这是2009年 - 我的机器可以处理额外的流程." 因此,就效率而言,授予.但是便携性确实让我感到非常重要.我经常使用Linux(Debian)和OS X.我已经学会了_never_以假设我想要的工具在两台机器上都可用(例如,OS X上没有`wget`开箱即用)或该死的东西需要相同的标志(例如,OS X上许多核心实用程序的BSD版本).我不做Windows,但显然如果你这样做会变得更复杂.所以我认为解散可移植性有点轻浮. (2认同)