要转义要用作shell参数的字符串,我们使用escapeshellarg()
中的函数PHP
。 Perl
是否具有等效功能?
答案 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手册页的声明:
- 用单引号括起字符可保留引号中每个字符的字面值。
- 单引号之间可能不会出现单引号,即使前面有反斜杠也是如此。
- 用双引号括起字符会保留引号内所有字符的字面值,但$,`除外, \,并且,当启用历史记录扩展时,!。
醇>
从(2.)我们知道反斜杠不能用来逃避单个qoutes,但是从(3.)它暗示双引号保留(aka escape)单引号的字面值。
另请注意,引号的唯一目的是更改引用字符的含义(不会创建特殊的字符串对象或类似的东西),并且在扩展后,所有连续的文字字符都连接在一起。然后,'foo''bar'
与foobar
相同。
上面的函数是单引号整个字符串,以便其中没有字符具有特殊含义。但是,为了允许单引号字符的存在,在找到这些字符的地方拆分字符串,并完成以下操作:先前的子字符串已完成('
),然后双引号单引号为引入("'"
)并启动下一个子字符串('
)。这就是为什么'
全局被'"'"'
替换的原因。
例如(伪代码):
foo'bar => 'foo' + "'" + 'bar'