Проблема с командной строкой Perl - PullRequest
1 голос
/ 10 апреля 2011

Я пишу программу на Perl, которая примет несколько аргументов командной строки (они на самом деле будут предоставлены другой программой) и откроет pdf-файл для конкретной страницы. Я основал его на здесь (см. Стр. 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, он возвращается к приглашению, и если я нажимаю Enter там, он дает мне вышеуказанную ошибку.

Ответы [ 3 ]

4 голосов
/ 10 апреля 2011

Когда 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{...} частей выполняется командной оболочкой по мере их появления, большинство из них, вероятно, являются синтаксическими ошибками. Ваша полная команда никогда не выполняется.

То, что вы, вероятно, хотели, было:

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

Который создает строку, а затем передает ее оболочке.

3 голосов
/ 10 апреля 2011

Backtick не работает так, как вы, кажется, думаете.

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

Это не выполняет команду cmd \c foo. Он выполняет команду cmd \c и принимает вывод, объединяет значение $foo с этим выводом. Вам необходимо создать всю команду и только затем передать ее оператору обратного удара.

3 голосов
/ 10 апреля 2011

Я думаю, вы немного озадачены тем, как работают обратные удары. Примерно так:

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 для большей безопасности.

...