我正在编写一个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,它就会返回一个提示符,如果我点击进入那里,它会给我上面的错误。
答案 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::Open2
或IPC::Open3
来提高安全性。
答案 2 :(得分:3)
Backtick不会像你想象的那样工作。
$var = "foo";
`cmd \c `.$foo
这不执行命令cmd \c foo
。它执行命令cmd \c
并获取输出,将$foo
的值连接到该输出。您需要构造整个命令,然后才将其提供给反引号操作符。