我想运行此命令,看到here:
diff <(echo "string1" ) <(echo "string2")
来自perl,我尝试了system
:
system('diff <(echo "string1" ) <(echo "string2")');
但它导致:
sh: 1: Syntax error: "(" unexpected
有人知道这个伎俩吗?
此外,如果从可能需要转义的两个变量中读取string1
和string2
,如何安全地运行此类命令?
答案 0 :(得分:4)
使用bash执行命令
system('/bin/bash -c \'diff <(echo "string1" ) <(echo "string2")\'');
默认情况下,系统将使用/ bin / sh执行命令,而/ bin / sh不支持功能'()'
对于安全运行,需要转义关键字符,例如。引用这里。
错误代码:
my $var1 = "\"string1;ls";
my $var2 = "\"string2;ls";
my $cmd = "diff <(echo \"$var1\") <(echo \"$var2\" )";
print $cmd . "\n";
my @args = ("bash", "-c", $cmd);
system(@args);
print "=======" . "\n";
安全代码:
$var1 = "\"string1;ls";
$var2 = "\"string2;ls";
$var1 =~ s/(\")/\\$1/g;
$var2 =~ s/(\")/\\$1/g;
$cmd = "diff <(echo \"$var1\") <(echo \"$var2\" )";
print $cmd . "\n";
@args = ("bash", "-c", $cmd);
system(@args);
答案 1 :(得分:1)
我正在修理这个,即使它没有处理空格(就像你想要的那样),它也不会引用第一个字符。我做得更聪明,所以它没有引用明显的东西。
# this will escape all the characters in the string
my $str = '/?\abc"';
( my $str3 = $str) =~ s/([^a-zA-Z0-9])/\\\1/g;
printf ("%s\n",$str);
printf ("%s\n",$str3);
my @args = ( "bash", "-c", 'diff <(echo "$foo" ) <(echo "string2")' );
system(@args);
答案 2 :(得分:0)
无shell(但可能不太便携)版本:
#!perl
use strict;
use warnings;
use Fcntl;
open my $one, '-|', 'echo', 'string1' or die "$! opening first input";
fcntl $one, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open first input";
open my $two, '-|', 'echo', 'string2' or die "$! opening second input";
fcntl $two, F_SETFD, (fcntl($two, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open second input";
open my $diff, '-|', 'diff', "/dev/fd/".fileno($one), "/dev/fd/".fileno($two)
or die "$! running diff";
while (<$diff>) {
print;
}
这基本上就是shell的作用(打开第一个“echo”命令的子进程,打开第二个“echo”命令的子进程,允许子进程继承其文件句柄,然后打开子进程到“diff”命令,其参数是指向打开的文件句柄的特殊文件名。唯一的区别是,我们不是让diff打印到屏幕上,而是捕获输出并自己打印 - 因为我认为你可能想要对输出做一些事情,而不仅仅是看它。 / p>
#!/usr/bin/perl
use strict;
use warnings;
use Fcntl;
my $pid_one = open my $one, '-|';
die "$! opening first input" unless defined $pid_one;
if (!$pid_one) { # child
print "string1\n";
exit;
}
fcntl $one, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open first input";
my $pid_two = open my $two, '-|';
die "$! opening second input" unless defined $pid_two;
if (!$pid_two) { # child
print "string2\n";
exit;
}
fcntl $two, F_SETFD, (fcntl($one, F_GETFD, 0) & ~FD_CLOEXEC)
or die "$! keeping open second input";
open my $diff, '-|', 'diff', "/dev/fd/".fileno($one), "/dev/fd/".fileno($two)
or die "$! running diff";
while (<$diff>) {
print;
}
string1
和string2
可以是任何内容,包括来自父进程的变量或其他命令的输出。