我有一个Perl脚本progA.pl
,需要使用progB.pl
命令运行另一个Perl脚本system
。但是,progB.pl
中的~/.bashrc
已有别名,因此我需要确保在加载~/.bashrc
后运行它。我可以使用bash
选项使用-lc
来实现此目的。
对于这个问题,我考虑以下版本的progB.pl
use feature qw(say);
use strict;
use warnings;
use Data::Dump qw(dd dump);
say "Received \@ARGV: " . dump @ARGV;
这里是progA.pl
:
use feature qw(say);
use strict;
use warnings;
use Data::Dump qw(dd dump);
my $cmd = qq(progB.pl --opt='This option contains '"'"'single'"'"' quotes');
say "cmd = " . dump($cmd);
system( "$cmd" );
say "-----";
system( 'bash -c ' . "$cmd" );
say "-----";
system( 'bash -c ' . "'$cmd'" );
say "-----";
system( "bash -c \"$cmd\"" );
正在运行
$ progA.pl
给出输出:
cmd = "progB.pl --opt='This option contains '\"'\"'single'\"'\"' quotes'"
Received @ARGV: "--opt=This option contains 'single' quotes"
-----
Received @ARGV: ()
-----
Received @ARGV: "--opt=This"
-----
Received @ARGV: "--opt=This option contains single quotes"
我们看到,在progB.pl
直接运行而不使用bash -c
时,此方法可以正常运行。当我使用bash -c
运行命令时,三个备选方案都没有正常工作。
如何使用包含单引号的参数运行progB.pl
并同时使用bash -c
?
答案 0 :(得分:2)
你应该首先避免这种引用疯狂,但如果你坚持,你应该使用system ARRAY
版本至少避免一个引用级别。
my $cmd = q{progB.pl --opt='This option contains '"'"'single'"'"' quotes'};
system( qw(bash -c), $cmd );
这只是引用疯狂的一个级别。
my $option = q{This option contains 'single' quotes} =~ s/'/'"'"'/gr; # '
my $cmd = qq{progB.pl --opt='$option'};
system( qw(bash -c), $cmd );
你可以做一些简单的帮手
sub sq ($) { "'" . $_[0] =~ s/'/'"'"'/gr . "'" } # "
my $option = q{This option contains 'single' quotes};
my $cmd = qq{progB.pl --opt=@{[sq $option]}};
system( qw(bash -c), $cmd );
答案 1 :(得分:0)
经过一些反复试验后,我到达了:
use feature qw(say);
use strict;
use warnings;
my $cmd = qq(print_first_arg.pl --opt='This option contains '"'"'single'"'"' quotes');
$cmd =~ s/'/'"'"'/g;
system( 'bash -c ' . "'$cmd'" );
对于这个测试案例,它似乎有效..
这也遵循@ysth在这个答案中建议的方法: https://stackoverflow.com/a/24869016/2173773