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::Open2IPC::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 命令行问题的主要内容,如果未能解决你的问题,请参考以下文章

小动作之perl命令行

Perl 命令行多行替换

Perl命令行模式1

Perl单行(Perl One-Liners)命令

从 Perl 脚本执行 .net 命令行应用程序

如何从命令行测试Perl CGI脚本的文件上传?