Perl 命令行问题
Posted
技术标签:
【中文标题】Perl 命令行问题【英文标题】:Perl command line problem 【发布时间】:2011-08-02 07:36:23 【问题描述】:我正在编写一个 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,它就会返回一个提示,如果我在那里按下回车,就会出现上述错误。
【问题讨论】:
您在组合命令字符串时是否使用了反引号 (`) 而不是单引号 (')? 是的,我正在使用反引号。反引号是 Tab 键上方的那个,对吧? 顺便说一句, cmd \c 应该是什么?它不应该读取 cmd /c 是的,Ingo,谢谢。这实际上清除了程序。 【参考方案1】:我认为您对反引号的工作原理有些困惑。像这样的:
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】:当 Perl 看到
my $c = `cmd \c "`.$ARGV[0].`" /A "page=`.$ARGV[1].`=OpenActions" "`.$ARGV[2].``;
它变成了这样的东西:
my $c = qxcmd \c ".$ARGV[0].qx" /A "page=.
$ARGV[1].qx=OpenActions" ".$ARGV[2].qx;
这些qx...
部分中的每一个都在遇到时由命令shell 执行,其中大部分可能是语法错误。您的完整命令永远不会运行。
你可能想要的是:
my $c = qxcmd \\c "$ARGV[0]" /A "page=$ARGV[1]=OpenActions" "$ARGV[2]";
构造字符串,然后将其传递给 shell。
【讨论】:
谢谢,这清除了反引号的事情。但是,我不想这么说,情况并没有改变。它仍然和以前一样...... 最后,即使有Ingo的回答,我原来的程序的命令也不起作用,所以我求助于这个。这就是为什么答案是这样的。【参考方案3】:反引号并不像您想象的那样工作。
$var = "foo";
`cmd \c `.$foo
这不会执行命令cmd \c foo
。它执行命令cmd \c
并获取输出,将$foo
的值连接到该输出。您需要构建整个命令,然后才将其提供给反引号运算符。
【讨论】:
这也教会了我更多关于 Perl 的知识……谢谢。我不知道(显然)。以上是关于Perl 命令行问题的主要内容,如果未能解决你的问题,请参考以下文章