Perl脚本中的Bash命令

时间:2014-06-20 22:14:47

标签: perl bash solaris

如何让以下Bash命令在Perl脚本中正确执行?

su - oracle -c  "echo \"select database_role from v\\\$database;\" | sqlplus -s / as sysdba";

当放入bash脚本时,该命令可以正确执行。但是在perl脚本中使用以下内容时:

my @roleQuery = `su - oracle -c  "echo \"select database_role from v\\\$database;\" | sqlplus -s / as sysdba"`;

返回:

sh:  | sqlplus -s / as sysdba: not found
Oracle Corporation      SunOS 5.10      Generic Patch   January 2005
 You have mail.
 select

我正在以同一个用户身份执行bash和perl脚本。

Bash输出(这是我想要的回报)

Oracle Corporation      SunOS 5.10      Generic Patch   January 2005
You have mail.

DATABASE_ROLE
----------------
PRIMARY

2 个答案:

答案 0 :(得分:2)

qx(反引号)遵循与qq(双引号)相同的规则。转义\$个字符。 (如果你有的话@。)

su - oracle -c  "echo \"select database_role from v\\\$database;\" | sqlplus -s / as sysdba";

执行
`su - oracle -c  "echo \\"select database_role from v\\\\\\\$database;\\" | sqlplus -s / as sysdba";`

答案 1 :(得分:0)

双引号字符串 - 需要大量转义

反引号运算符`STRING`qx/STRING/同义,其行为类似于插入变量的双引号字符串。因此,必须转义以下字符才能将它们视为文字:$@\以及用作分隔符的任何字符。

my @roleQuery = `su - oracle -c  "echo \\"select database_role from v\\\\\\\$database;\\" | sqlplus -s / as sysdba";`

单引号字符串 - 减少转义

perlop Quote-Like Operators中记录了一个技巧:

  

使用单引号作为分隔符可以保护命令不受Perl的双引号插值的影响,而是将其传递给shell:

     $perl_info  = qx(ps $$);       # that's Perl's $$
     $shell_info = qx'ps $$';       # that's the new shell's $$

当然,单引号字符串仍需要单引号进行转义,并且字符串末尾需要多个反斜杠或反斜杠。这会将您的转义减少到连续的三个反斜杠:

my @roleQuery = qx'su - oracle -c  "echo \"select database_role from v\\\\\\$database;\" | sqlplus -s / as sysdba"';

单引号Heredoc - 无逃脱

为避免需要转义,您可以使用单引号heredoc将命令分配给变量。这会增加一个步骤,但是如果已经有两个不同的转义级别,这可能会有所帮助。此外,如果附加换行无关紧要,您可以删除chomp。

chomp(my $rolecmd = <<'END_COMMAND');
su - oracle -c  "echo \"select database_role from v\\\$database;\" | sqlplus -s / as sysdba"
END_COMMAND

my @roleQuery = `$rolecmd`;