2

我遇到了一些代码问题,我想知道是否有人可以提供帮助。

基本上我正在尝试对数据库执行 isql 查询并将其分配给标量变量。isql 命令使用定义为管道符号的列分隔符。

所以我把它设置成这样:

my $command = "isql -S -U -s| -i";
my $isql_output = `$command`;

isql 命令单独工作,但当作为反引号发出时,它会在管道处停止。我尝试$command使用子字符串连接字符串,使用单引号和反斜杠转义项等-s\"\|\"无济于事。我也尝试过使用qx而不是反引号。

不幸的是,我目前使用的是旧版本的 perl (v5.6.1),升级范围有限,所以我不确定我是否能解决这个问题。

4

3 回答 3

4

|您必须以shell 无法将其识别为特殊字符的方式引用。两种方式:

  1. -s|放入单引号中:'-s|'. Perl 将在双引号字符串中单独留下单引号,并将它们不加修改地传递给 shell。
  2. |用两个反斜杠转义:-s\\|. 为什么是两个?Perl 看到第一个字符,告诉它不加修改地传递下一个字符。因此,shell 看到-s\|并做了一些非常相似的事情:它看到单个\并且知道不处理下一个字符|,,特殊。
于 2012-12-10T12:49:51.427 回答
1

问题是该命令是通过外壳执行的。您可以通过在列表而不是单个字符串中传递命令和参数来避免这种情况。反引号结构不支持这一点,因此您需要改用该open()函数。我没有测试以下代码,但它给出了这个想法:

my @command = (qw(isql -Sserver -Uuser -Ppassword -s| -w4096), '–i' . $file);
print join(' ', @command), "\n";
open(my $fh, '-|', @command)
  or die "failed to run isql command: $@\n";
my @isql_output = <$fh>;
close($fh);
my $isql_output = $isql_output[0]; chomp($isql_output);

如果您正在使用 15 年前的 Perl 版本(Oracle 用户倾向于这样做),我不确定这是否会得到支持。例如,您可能需要编写chop而不是chomp.

更新:根据文档,问题不在于 Perl 版本,而是 Windows 不支持此构造。这必须是合格的:我在 Cygwin 上使用 Perl,它在那里工作得很好,但我不知道你是否可以使用 Cygwin。

于 2012-12-10T14:05:43.477 回答
0

单引号应该可以工作。尝试运行测试 perl 脚本:

my $cmd = "./test.sh -S -U -s '|' -i";
print `$cmd`;

使用 test.sh:

#!/bin/sh

echo $@

输出应该是-S -U -s | -i

于 2012-12-10T12:56:50.213 回答