Perl命令行问题

时间:2011-04-10 01:01:53

标签: perl command-line command-line-arguments command-prompt

我正在编写一个Perl程序,它将采用一些命令行参数(它们实际上将由另一个程序提供)并打开一个特定页面的pdf。我的基础是here(见第5页)。我已经从命令行直接测试了命令,它完全符合我的要求。现在我试图从Perl中做到这一点,它似乎没有起作用。我得到的错误是:

The process tried to write to a nonexistent pipe

这是代码......有人可以告诉我我做错了吗?

#!C:/perl/bin/perl
use strict;
use warnings;
use diagnostics;

my $c = `cmd \c "`.$ARGV[0].`" /A "page=`.$ARGV[1].`=OpenActions" "`.$ARGV[2].``;
print $c;
system "Pause";

此后我得到的是cmd中的空白区域。一旦我按下Ctrl + C,它就会返回一个提示符,如果我点击进入那里,它会给我上面的错误。

3 个答案:

答案 0 :(得分:4)

当Perl看到

my $c = `cmd \c "`.$ARGV[0].`" /A "page=`.$ARGV[1].`=OpenActions" "`.$ARGV[2].``;

它变成了这样的东西:

my $c = qx{cmd \c "}.$ARGV[0].qx{" /A "page=}.
        $ARGV[1].qx{=OpenActions" "}.$ARGV[2].qx{};

这些qx{...}部分中的每一部分都在遇到命令shell时执行,其中大多数可能是语法错误。你的完整命令永远不会运行。

你可能想要的是:

my $c = qx{cmd \\c "$ARGV[0]" /A "page=$ARGV[1]=OpenActions" "$ARGV[2]"};

构造字符串,然后将其传递给shell。

答案 1 :(得分:3)

我认为你对反击的工作方式有点困惑。像这样:

my $c = `/where_is/pancake_house`

将运行/where_is/pancake_house命令并将其标准输出上打印的内容放入$c。反引号也插入双引号字符串。你还必须逃避反斜杠。

所以,你不需要在命令中使用多组反引号,也不需要像这样将事物粘贴在一起。像这样:

my $c = `cmd \\c "$ARGV[0]" /A "page=$ARGV[1]=OpenActions" "$ARGV[2]`;

应该没问题。当然,如果ARGV值包含空格或引号或其他有趣的内容,您仍会遇到问题。您可能希望使用IPC::Open2IPC::Open3来提高安全性。

答案 2 :(得分:3)

Backtick不会像你想象的那样工作。

$var = "foo";
`cmd \c `.$foo

这不执行命令cmd \c foo。它执行命令cmd \c并获取输出,将$foo的值连接到该输出。您需要构造整个命令,然后才将其提供给反引号操作符。