许多开始的程序员编写如下代码:
sub copy_file ($$) { my $from = shift; my $to = shift; `cp $from $to`; }
这是坏的,为什么?应该使用反引号吗?如果是这样,怎么办?
解决方法
有几个人已经提到你应该只使用反引号:
>您需要捕获(或抑制)输出.
>没有内置函数或Perl模块执行相同的任务,或者您有很好的理由不使用模块或内置.
>你消化你的输入.
你检查返回值.
不幸的是,正确检查返回值的事情可能相当具有挑战性.它死了信号吗?是否完成,但返回有趣的退出状态?尝试解释$的标准方法?只是可怕
我建议使用IPC::System::Simple模块的capture()和system()函数,而不是反引号. capture()函数就像反引号一样工作,除了:
>它提供详细的诊断,如果命令不启动,被信号杀死,或返回意外的退出值.
>如果通过了污染数据,它将提供详细的诊断.
>它提供了一个简单的机制来指定可接受的退出值.
>它允许你调用反引号没有shell,如果你想.
>它提供了避免shell的可靠机制,即使您使用单个参数.
与Perl的内置系统()不同,这些命令也可以一致地运行,Perl的内置系统()可能会在较旧版本的Perl(例如,具有多个参数的5.6.0版本)中使用多个参数调用时检查受污染的数据,或者可以在Windows下调用shell.
例如,以下代码片段将把对perldoc的调用结果保存到一个标量中,避免了shell,如果无法找到该页面,则抛出异常(因为perldoc返回1).
#!/usr/bin/perl -w use strict; use IPC::System::Simple qw(capture); # Make sure we're called with command-line arguments. @ARGV or die "Usage: $0 arguments\n"; my $documentation = capture('perldoc',@ARGV);
IPC::System::Simple是纯Perl,工作在5.6.0及以上,并没有任何依赖关系通常不会与您的Perl分发. (在Windows上,它取决于ActiveState和Strawberry Perl附带的Win32 ::模块).
免责声明:我是IPC::System::Simple的作者,所以我可能会表现出一些偏见.