my @cmd = qw(ls -l "dir with spaces");
#my @cmd = qw(ls -l "dir with spaces" > outfile);
my @out = qx(@cmd);
print for @out;
我创建了一个"dir with spaces"目录,其中包含一个要测试的文件(对于带引号的命令,需要使用shell)。 接下来,原则上我会推荐一个模块来编写这些shell命令,而不是像String::ShellQuote那样通过一个令人头痛的过程来正确地转义并传递所有命令
use String::ShellQuote qw(shell_quote);
my @cmd = ('ls', '-l', q(dir with spaces));
my $quoted = shell_quote(@cmd);;
my @out = qx($quoted);
#my @out = qx($quoted > outfile);
print for @out;
use Shell::Quote qw( shell_quote );
my $cmd = shell_quote( @cmd );
my $output = `$cmd`;
die "Can't spawn child: $!\n" if $? == -1;
die "Child killed by signal ".( $? & 0x7F )."\n" if $? & 0x7F;
die "Child exited with error ".( $? >> 8 )."\n" if $? >> 8;
或
use IPC::System::Simple qw( capturex );
my $output = capturex( @cmd );
或
use IPC::Run qw( run );
run \@cmd, '>', \my $output;
die "Child killed by signal ".( $? & 0x7F )."\n" if $? & 0x7F;
die "Child exited with error ".( $? >> 8 )."\n" if $? >> 8;
6条答案
按热度按时间i86rm4rw1#
对于一个,一个 * 可以 * 提交一个列表到
qx
;它被插入到一个字符串中,然后传递给execvp
或shell(参见qx,以及this post的第二部分和注解)。如果您 * 需要 * 一个shell,那么假定该字符串包含shell元字符,因此它将通过shell传递。我创建了一个
"dir with spaces"
目录,其中包含一个要测试的文件(对于带引号的命令,需要使用shell)。接下来,原则上我会推荐一个模块来编写这些shell命令,而不是像String::ShellQuote那样通过一个令人头痛的过程来正确地转义并传递所有命令
我使用
q(...)
运算符形式的单引号来演示另一种方法(包含单引号也很有用);对于这个简单的例子来说,这是不必要的。2人们仍然需要注意细节;这是使用复杂外部命令的本质,任何方法或工具都 * 无法 * 完全避免。至于运行
bash
,请注意,通常情况下,sh
会委托给系统上的默认shell,并且在许多系统上使用的是bash
。我想再提几点意见:
qx
是一个古老的恶魔。使用现代的工具/模块运行外部命令怎么样?为了准备你所涉及的bash字符串,可能需要做更多的工作,但其他一切都会更好。选项很多。例如system
调用pbpqsu0x2#
Capture::Tiny是一个非常好的选项:如概要所示,您可以
如果您需要更简单的反勾行为,也可以使用systeminner
capture_stdout
。另外,它是非常通用的,可以处理Perl代码(甚至是做奇怪事情的Perl代码)以及外部程序,所以在您的工具箱中有它是一件好事。
yzckvree3#
我有下面的潜艇
输出为
我的回答是冗长的,但它满足了我的需要。我希望Perl有一个内置的解决方案,就像它如何处理system()调用一样,我仍然希望。
8ljdwjyq4#
给定
您可以使用下列任一项:
或
或
xwmevbvl5#
您可以更改perl使用的shell:
64jmpszr6#
您可以使用单引号作为
qx
的分隔符,如下所示:这将根据perlop保护命令不受Perl的双引号插入的影响。
不幸的是,这对单引号不起作用。例如,如果你想执行
echo "'"
,你需要以下代码:编辑:
为了帮助您管理引号的转义,您可以使用如下的helper函数: