我有一个Perl脚本,其中包含变量$env->{'arguments'}
,该变量应包含一个JSON对象,我想将该JSON对象作为参数传递给我的其他外部脚本,并使用反引号来运行它。
$env->{'arguments'}
在转义前的值:
$VAR1 = '{"text":"This is from module and backslash \\ should work too"}';
转义后的$env->{'arguments'}
的值:
$VAR1 = '"{\\"text\\":\\"This is from module and backslash \\ should work too\\"}"';
代码:
print Dumper($env->{'arguments'});
escapeCharacters(\$env->{'arguments'});
print Dumper($env->{'arguments'});
my $command = './script.pl '.$env->{'arguments'}.'';
my $output = `$command`;
转义符功能:
sub escapeCharacters
{
#$env->{'arguments'} =~ s/\\/\\\\"/g;
$env->{'arguments'} =~ s/"/\\"/g;
$env->{'arguments'} = '"'.$env->{'arguments'}.'"';
}
我想问你什么是正确的方法,以及如何将JSON字符串解析为有效的JSON字符串,我可以将其用作脚本的参数。
答案 0 :(得分:2)
您正在重新发明wheel。
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote('./script.pl', $env->{arguments});
my $output = `$cmd`;
或者,您可以使用许多IPC ::模块来代替qx
。例如,
use IPC::System::Simple qw( capturex );
my $output = capturex('./script.pl', $env->{arguments});
因为至少有一个参数,所以也可以使用以下参数:
my $output = '';
open(my $pipe, '-|', './script.pl', $env->{arguments});
while (<$pipe>) {
$output .= $_;
}
close($pipe);
请注意,当前目录不一定是包含执行脚本的目录。如果要执行与当前正在执行的脚本位于同一目录中的script.pl
,则需要进行以下更改:
添加
use FindBin qw( $RealBin );
并替换
'./script.pl'
使用
"$RealBin/script.pl"
答案 1 :(得分:1)
将其传递到第二个程序而不是将其作为参数传递似乎更有意义(并且更加安全)。
test1.pl
#!/usr/bin/perl
use strict;
use JSON;
use Data::Dumper;
undef $/;
my $data = decode_json(<>);
print Dumper($data);
test2.pl
#!/usr/bin/perl
use strict;
use IPC::Open2;
use JSON;
my %data = ('text' => "this has a \\backslash", 'nums' => [0,1,2]);
my $json = JSON->new->encode(\%data);
my ($chld_out, $chld_in);
print("Executing script\n");
my $pid = open2($chld_out, $chld_in, "./test1.pl");
print $chld_in "$json\n";
close($chld_in);
my $out = do {local $/; <$chld_out>};
waitpid $pid, 0;
print(qq~test1.pl output =($out)~);