Почему * в моей трубе, открытой в Perl, не работает на Windows? - PullRequest
3 голосов
/ 11 июля 2009

У меня странная проблема с Perl. Я пытаюсь выполнить внешнюю программу из моего скрипта Perl, и эта внешняя программа принимает строку + подстановочный знак в качестве параметров. Моя Perl-программа выглядит так

my $cmd_to_run = 'find-something-in-somedb myname* |' 
open(procHandle, $cmd_to_run); # I am using open because I want to 
                               # parse the output using pipes

По какой-то странной причине при запуске этого скрипта Perl (под Windows) вызов функции open заканчивается ошибкой:

'sqlselect' is not recognized as an internal or external command

Я догадался, что это как-то связано с *, присутствующим в моей командной строке, и, следовательно, я удалил ее, и теперь моя командная строка выглядит следующим образом

my $cmd_to_run = 'find-something-in-somedb myname|'

Теперь, когда я запускаю свой Perl-скрипт, он работает отлично. Проблема возникает только при наличии подстановочного знака.

Некоторые моменты, на которые следует обратить внимание:

  1. Я выполнил ту же команду с символом подстановки, в том же приглашении cmd (где я выполняю этот сценарий Perl), и она прекрасно работает ..

  2. Та же команда работает, когда я программирую ее на C, используя функцию _open в Windows.

  3. Проблема, кажется, только при наличии подстановочного знака *, по крайней мере, это то, что я предполагаю

  4. Нет, я не пробовал это в Unix ..

Какие-нибудь подсказки ???

РЕДАКТИРОВАТЬ : Я обнаружил, что это как-то связано с ENV. Программа, которую я пытаюсь запустить, использует "sqlselect", только когда в строке поиска присутствует подстановочный знак "*" ... И find-what-in-somedb, и sqlselect находятся в одном месте. В каком случае perl может найти «find-in-db», а не «sqlselect»

Извините, я понимаю, что оригинальная проблема теперь оказывается чем-то другим ... Что-то, что связано с "ENV", а не с Wildcard *

Ответы [ 3 ]

6 голосов
/ 11 июля 2009

Рекомендуется использовать форму с тремя аргументами open

open(procHandle, '-|', 'find-something-in-somedb', 'myname*');

, поскольку это обходит оболочку (которая будет выполнять расширение *).

Однако в Windows приложения часто выполняют собственный синтаксический анализ и расширение *, поэтому вам может понадобиться

open(procHandle, '-|', 'find-something-in-somedb', '"myname*"');

или даже

open(procHandle, '-|', 'find-something-in-somedb "myname*"');

поскольку я не совсем уверен, как и когда Perl передает вещи cmd.

3 голосов
/ 11 июля 2009

Весьма вероятно, что Perl расширяет сам подстановочный знак, чего вы не хотите делать. Ответ, предоставленный ephemient , очень хорош, но для устранения этой проблемы попробуйте вызвать действительно простую программу:

print join ' ', @ARGV;

Поместите это в свой собственный файл, затем вызовите его из исходной программы (я назвал мой argv.pl):

my $cmd_to_run = './argv.pl myname* |' 
open(procHandle, $cmd_to_run); 

Это определенно скажет вам на вашей платформе, как Perl анализирует вещи. В Unix * расширяется, чтобы соответствовать файлам в текущем рабочем каталоге. Не уверен насчет Windows, хотя.

0 голосов
/ 11 июля 2009

Что произойдет, если вы используете три аргумента open?

open my $procHandle, '-|', 'find-something-in-somedb myname*'
    or die "Cannot open pipe: $!";
...