当前位置:  开发笔记 > 编程语言 > 正文

什么时候(和错误的时间)使用反引号?

如何解决《什么时候(和错误的时间)使用反引号?》经验,为你挑选了5个好方法。

许多初学程序员编写如下代码:

sub copy_file ($$) {
  my $from = shift;
  my $to = shift;

  `cp $from $to`;
}

这是不好的,为什么?是否应该使用反引号?如果是这样,怎么样?



1> pjf..:

有些人已经提到过你应该只在以下情况下使用反引号:

您需要捕获(或抑制)输出.

没有内置函数或Perl模块来执行相同的任务,或者您有充分的理由不使用模块或内置.

您清理您的输入.

您检查返回值.

不幸的是,正确检查返回值等事情可能非常具有挑战性.它死于信号吗?它是否已完成,但返回一个有趣的退出状态?尝试解释的标准方法$?很糟糕.

我建议使用IPC :: System :: Simple模块capture()system()函数而不是反引号.该capture()功能就像反引号一样,除了:

如果命令未启动,被信号终止或返回意外退出值,它将提供详细的诊断.

如果传递了污染数据,它会提供详细的诊断.

它提供了一种指定可接受退出值的简单机制.

如果你愿意,它允许你在没有shell的情况下调用反引号.

它提供了可靠的机制来避免shell,即使你使用单个参数.

这些命令在操作系统和Perl版本中也可以一致地工作,不像Perl的内置版本,system()当在旧版本的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的作者,所以我可能会表现出一些偏见.



2> Ovid..:

规则很简单:如果你能找到一个内置工作来做同样的工作,或者如果它们是CPAN上的一个强大的模块,它将为你做这件事,从不使用反引号.反引号通常依赖于不可移植的代码,即使你解开变量,你仍然可以打开很多安全漏洞.

除非你已经非常严格地指定允许的内容(不是不允许的内容 - 你会错过任何内容),否则永远不要使用反引号和用户数据!这非常非常危险.



3> raldi..:

当且仅当您需要捕获命令的输出时,才应使用反引号.否则,应使用system().当然,如果有一个Perl函数或CPAN模块来完成这项工作,那么应该使用它来代替它们.

在任何一种情况下,都强烈鼓励两件事:

首先,清理所有输入:如果代码暴露于可能的不可信输入,则使用污点模式(-T).即使不是,也要确保处理(或防止)像空格或三种引用这样的时髦字符.

其次,检查返回代码以确保命令成功.以下是如何执行此操作的示例:

my $cmd = "./do_something.sh foo bar";
my $output = `$cmd`;

if ($?) {
   die "Error running [$cmd]";
}



4> Dan..:

如果要从命令收集输出,请使用反引号.

否则system()是更好的选择,特别是如果您不需要调用shell来处理元字符或命令解析.你可以通过将一个列表传递给system()来避免这种情况,例如system('cp', 'foo', 'bar')(但是你可能会更好地为那个特定的例子使用一个模块:))



5> Erik Johanse..:

捕获stdout的另一种方法(除了pid和退出代码)是使用IPC :: Open3可能否定系统和反引号的使用.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有