我注意到当我在perl中使用反引号时,命令是使用sh而不是bash执行的,这给我带来了一些问题。
如何改变这种行为,以便perl使用bash?
PS。我正在尝试运行的命令是:
paste filename <(cut -d \" \" -f 2 filename2 | grep -v mean) >> filename3
答案 0 :(得分:7)
“系统shell”通常不可变。见perldoc -f exec:
如果LIST中有多个参数,或者LIST是一个具有多个值的数组,则使用LIST中的参数调用execvp(3)。如果 只有一个标量参数或一个包含一个元素的数组,参数检查是否为shell元字符,如果有,则为 整个参数传递给系统的命令shell进行解析(在Unix平台上这是“/ bin / sh -c”,但在其他平台上有所不同)。
如果您真的需要bash来执行特定任务,请考虑明确调用它:
my $result = `/usr/bin/bash command arguments`;
甚至:
open my $bash_handle, '| /usr/bin/bash' or die "Cannot open bash: $!";
print $bash_handle 'command arguments';
您也可以将bash命令放入.sh文件中并直接调用它:
my $result = `/usr/bin/bash script.pl`;
答案 1 :(得分:7)
尝试
`bash -c \"your command with args\"`
我很确定-c的参数被解释为bash解释其命令行的方式。诀窍是保护它不受sh
的影响 - 这就是引用的目的。
答案 2 :(得分:5)
此示例适用于我:
$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
答案 3 :(得分:1)
为了处理运行bash和嵌套引号,本文提供了最佳解决方案:How can I use bash syntax in Perl's system()?
my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);
答案 4 :(得分:0)
我认为perl
会尊重$SHELL
变量,但后来我发现它的行为可能实际上取决于系统的exec
实现。在我看来,似乎是exec
将执行shell (/ bin / sh)的路径 将file作为其第一个参数。
你总是可以qw/bash your-command/
,不是吗?
答案 5 :(得分:0)
创建一个perl子例程:
sub bash { return `cat << 'EOF' | /bin/bash\n$_[0]\nEOF\n`; }
并使用如下:
my $bash_cmd = 'paste filename <(cut -d " " -f 2 filename2 | grep -v mean) >> filename3';
print &bash($bash_cmd);
或者使用perl here-doc进行多行命令:
$bash_cmd = <<'EOF';
for (( i = 0; i < 10; i++ )); do
echo "${i}"
done
EOF
print &bash($bash_cmd);