bash - 使用 bash 的 Perl 反引号

标签 bash perl backticks

在 Perl 中,执行反引号的默认 shell 是 sh。我想改用 bash 来获得更丰富的语法。到目前为止,我发现建议的解决方案是

`bash -c \"echo a b\"`

明显的缺点是转义双引号,这意味着我将很难在我的 bash args 中使用双引号。例如,如果我想在 bash 中运行需要双引号的命令

echo "a'b"

上面的方法会很别扭。

Perl 的 system() 调用有解决这个问题的方法:使用 ARRAY args,

system("bash", "-c", qq(echo "a'b"));

这使我原来的 bash 命令保持不变,而且几乎总是如此。

我也想在反引号中使用 ARRAY args。可能吗?

最佳答案

例如,可以qx 提交列表;它被插入到一个字符串中,然后传递给 execvp 或 shell(参见 qxthis post 的第二部分和注释)。如果您需要一个 shell,那么大概该字符串包含 shell 元字符,因此它通过 shell。

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;

我使用单引号的 q(...) 运算符形式来演示另一种方式(对于包含单引号也很有用);这个简单的例子没有必要。人们仍然需要注意细节;这是使用复杂外部命令的本质,无法通过任何方法或工具完全避免。

至于运行 bash,请注意通常 sh 委托(delegate)给系统上的默认类型 shell,在许多系统上它是 bash 被使用。但如果它不在您的身上,在命令中使用 bash -c 的一种方法是首先准备命令,然后将其添加到 qx 字符串

my @cmd = ('ls', '-l', q(dir with spaces)); 
my $quoted = shell_quote(@cmd); 
my @out = qx(bash -c "$quoted"); 
#my @out = qx(bash -c "$quoted" > outfile); 
print for @out;

我想提供更多注意事项:

  • qx 是远古恶魔。如何使用现代工具/模块来运行外部命令?为了准备您涉及的 bash 字符串,可能需要做更多的工作,但其他一切都会更好。选择比比皆是。例如

  • 为什么要使用外部命令,而 Perl 的(远远)更丰富?它是一种完整的、非常完整的编程语言,而不是具有某些编程功能的命令解释器。如果您需要 shell 的功能,为什么不通过 shell 只运行那些东西,而在 Perl 中做所有其他事情呢?

关于bash - 使用 bash 的 Perl 反引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71033653/

相关文章:

r - 在 Rmarkdown 中执行 Perl 6 代码

node.js - Perl 的反引号在 Node.js 中的等价物是什么?

mysql - 需要在cron作业中添加mysql查询

c++ - 如何通过cpp程序将参数传递给bash脚本

linux - 以父脚本的用户身份运行 shell 下标

linux - 如何将stderr和stdout重定向到脚本同一行中的不同文件?

java - 如何将 perl 脚本嵌入到 jar 文件中执行?

perl - Ubuntu |变异效应预测器 | DBD mysql 设置失败

bash - bash 中反引号中使用的有效命令?

shell脚本无法将命令行的输出保存到变量中