Perl相当于PHP的escapeshellarg

时间:2010-07-09 11:25:03

标签: php perl

要转义要用作shell参数的字符串,我们使用escapeshellarg()中的函数PHPPerl是否具有等效功能?

4 个答案:

答案 0 :(得分:31)

String::ShellQuote,但大部分时间都不需要这样做。您可以通过仔细编程来避免调用shell。例如,system takes a list of arguments而不是字符串。

最佳实践:

use IPC::System::Simple qw(systemx);
systemx($command, @arguments);

require IPC::System::Simple;
use autodie qw(:all);
system([@allowed_exit_values], $command, @arguments);

答案 1 :(得分:3)

Perl可以匹配以下陈述的功能:

  

在字符串周围添加单引号,并引用/转义任何现有的单引号

     

http://php.net/manual/en/function.escapeshellarg.php#function.escapeshellarg

像这样:

sub php_escapeshellarg { 
    my $str = @_ ? shift : $_;
    $str =~ s/((?:^|[^\\])(?:\\\\)*)'/$1'\\''/g;
    return "'$str'";
}

答案 2 :(得分:1)

我必须同意@daxim。但是在某些情况下你不能使用它,比如将套接字上的命令传递给非perl或没有IPC模块的程序。我也查看了@axeman给出的正则表达式,这对我来说似乎有点复杂。我可能是错的,但我认为你不需要在命令的单引号字符串中转义反斜杠。所以,你可以这样做:

sub escapeshellarg {
    my $arg = shift;

    $arg =~ s/'/'\\''/g;
    return "'" . $arg . "'";
}

如果有任何理由,为什么这可能是不安全的,我想知道。我使用任何我想到的技巧来测试它,使shell执行任意代码,但没有成功,这让我觉得这个regexp与PHP实现相同。

在PHP实现中,它声明它所做的只是:在字符串周围添加单引号并引用/转义任何现有的单引号。

这是正则表达式的唯一功能。 想法?

答案 3 :(得分:1)

这个适用于我的BASH:

sub escape_shell_param($) {
   my ($par) = @_;
   $par =~ s/'/'"'"'/g;  # "escape" all single quotes
   return "'$par'";      # single-quote entire string
 }

它基于以下来自BASH手册页的声明:

  
      
  1. 用单引号括起字符可保留引号中每个字符的字面值。
  2.   
  3. 单引号之间可能不会出现单引号,即使前面有反斜杠也是如此。
  4.   
  5. 用双引号括起字符会保留引号内所有字符的字面值,但$,`除外,   \,并且,当启用历史记录扩展时,!。
  6.   

从(2.)我们知道反斜杠不能用来逃避单个qoutes,但是从(3.)它暗示双引号保留(aka escape)单引号的字面值。

另请注意,引号的唯一目的是更改引用字符的含义(不会创建特殊的字符串对象或类似的东西),并且在扩展后,所有连续的文字字符都连接在一起。然后,'foo''bar'foobar相同。

上面的函数是单引号整个字符串,以便其中没有字符具有特殊含义。但是,为了允许单引号字符的存在,在找到这些字符的地方拆分字符串,并完成以下操作:先前的子字符串已完成('),然后双引号单引号为引入("'")并启动下一个子字符串(')。这就是为什么'全局被'"'"'替换的原因。

例如(伪代码):

foo'bar => 'foo' + "'" + 'bar'