perl 反引号:使用 bash 而不是 sh
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3374082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
perl backticks: use bash instead of sh
提问by David B
I noticed that when I use backticks in perl the commands are executed using sh, not bash, giving me some problems.
我注意到当我在 perl 中使用反引号时,命令是使用 sh 而不是 bash 执行的,这给我带来了一些问题。
How can I change that behavior so perl will use bash?
如何更改该行为以便 perl 使用 bash?
PS. The command that I'm trying to run is:
附注。我试图运行的命令是:
paste filename <(cut -d \" \" -f 2 filename2 | grep -v mean) >> filename3
回答by Ether
The "system shell" is not generally mutable. See perldoc -f exec:
“系统外壳”通常不是可变的。查看perldoc -f exec:
If there is more than one argument in LIST, or if LIST is an array with more than one value, calls execvp(3) with the arguments in LIST. If there is only one scalar argument or an array with one element in it, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms).
如果 LIST 中有多个参数,或者 LIST 是具有多个值的数组,则使用 LIST 中的参数调用 execvp(3)。如果只有一个标量参数或一个包含一个元素的数组,则检查该参数是否有 shell 元字符,如果有,则将整个参数传递给系统的命令 shell 进行解析(这是“/bin/sh -c" 在 Unix 平台上,但在其他平台上有所不同)。
If you really need bash to perform a particular task, consider calling it explicitly:
如果您确实需要 bash 来执行特定任务,请考虑显式调用它:
my $result = `/usr/bin/bash command arguments`;
or even:
甚至:
open my $bash_handle, '| /usr/bin/bash' or die "Cannot open bash: $!";
print $bash_handle 'command arguments';
You could also put your bash commands into a .sh file and invoke that directly:
您还可以将 bash 命令放入 .sh 文件并直接调用:
my $result = `/usr/bin/bash script.pl`;
回答by Ether
Try
尝试
`bash -c \"your command with args\"`
I am fairly sure the argument of -c is interpreted the way bash interprets its command line. The trick is to protect it from sh- that's what quotes are for.
我相当确定 -c 的参数是按照 bash 解释其命令行的方式来解释的。诀窍是保护它免受sh- 这就是引号的用途。
回答by Paused until further notice.
This example works for me:
这个例子对我有用:
$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
回答by joseph
To deal with running bash and nested quotes, this article provides the best solution: How can I use bash syntax in Perl's system()?
为了处理运行 bash 和嵌套引号,本文提供了最佳解决方案:如何在 Perl 的 system() 中使用 bash 语法?
my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);
回答by bruce
Create a perl subroutine:
创建一个 perl 子程序:
sub bash { return `cat << 'EOF' | /bin/bash\n$_[0]\nEOF\n`; }
And use it like below:
并像下面这样使用它:
my $bash_cmd = 'paste filename <(cut -d " " -f 2 filename2 | grep -v mean) >> filename3';
print &bash($bash_cmd);
Or use perl here-doc for multi-line commands:
或者对多行命令使用 perl here-doc:
$bash_cmd = <<'EOF';
for (( i = 0; i < 10; i++ )); do
echo "${i}"
done
EOF
print &bash($bash_cmd);
回答by Pedro Silva
I thought perlwould honor the $SHELLvariable, but then it occurred to me that its behavior might actually depend on your system's execimplementation. In mine, it seems that exec
我以为perl会尊重该$SHELL变量,但后来我想到它的行为实际上可能取决于您系统的exec实现。在我看来,exec
will execute the shell (/bin/sh) with the path of the file as its first argument.
将使用文件的路径作为第一个参数执行 shell (/bin/sh)。
You can always do qw/bash your-command/, no?
你总是可以的qw/bash your-command/,不是吗?

