如何让以下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
答案 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将命令分配给变量。这会增加一个步骤,但是如果已经有两个不同的转义级别,这可能会有所帮助。此外,如果附加换行无关紧要,您可以删除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`;