Вызов подпрограммы с системной командой внутри другого скрипта
Я использую Perl под Windows 7 x86 и получаю сообщение об ошибке при вызове подпрограммы, которая выполняет внешние команды из другого скрипта.
У меня есть два сценария, script1 имеет подпрограмму, которая выполняет программу (patt.exe
) и script2, которые используют эту подпрограмму через require
,
Когда я запускаю script1, он работает правильно. Но когда я пытаюсь использовать эту подпрограмму из script2, я получаю следующую ошибку.
Ошибка:
'patt.exe' is not recognized as an internal or external command, operable program or batch file.
script1:
#patt('file.txt');
sub patt {
my $filename=shift@;
system("cmd.exe /c patt.exe -S $filename");
}
1;
script2:
require 'sub-directory/script1.pl';
patt('file.txt');
Следует отметить, что script1 и patt.exe находятся в подкаталоге (require 'sub-directory/script1.pl';
) и когда я помещаю все файлы в один каталог (require 'script1.pl';
) все работает правильно. Эта проблема остается, если я использую qx
или когда я передаю аргументы скрипту как массив.
Я был бы очень благодарен, если бы кто-нибудь мог мне помочь.
2 ответа
Одним из решений является то, что вы можете изменить текущий рабочий каталог на каталог вашей внешней программы. Для этого вы можете использовать __FILE__
переменная perl-скрипта, которая находится в той же директории, что и ваша программа.
Конечно, стоит отметить, что вам, вероятно, нужно будет предоставить полные пути к вашему $filename
если вы идете с этим решением:
use strict;
use warnings;
use Cwd;
use File::Spec;
sub patt {
my $filename = shift;
# Temporarily change cwd
my $oldcwd = cwd;
my ($vol, $path) = File::Spec->splitpath(__FILE__);
chdir($path);
# Execute program. Note that $filename will likely need to be a fully qualified path
system("patt.exe -S $filename");
# Revert cwd
chdir($oldcwd);
}
1;
Прежде всего, вам не нужно звонить pratt.exe
с помощью cmd.exe
, Вы должны быть в состоянии сделать это:
system "patt.exe -S $filename";
Ошибка происходит из-за того, что системная команда не может найти команду patt.exe
чтобы выполнить его. Попробуй это:
warn "WARN: \@INC: " . join "\n ", $ENV{PATH};
Это распечатает все каталоги, в которых будет выполняться поиск исполняемого файла. Обычно в Windows текущий каталог является последней записью в $PATH
, Я не уверен на 100%, как require
работает по отношению к текущему рабочему каталогу. Например, может случиться так, что когда вы помещаете подпрограмму в файл в другом каталоге, она не может найти pratt.exe
находится в текущем каталоге, поскольку текущий каталог находится там, где находится подпрограмма.
Итак, еще одна вещь, которую вы можете сделать, это использовать Cwd
импортировать cad
команда:
use strict; # Always! This will help point to errors.
use warnings; # Always! This will help point to errors.
use Cwd;
sub patt {
my $filename = shift;
warn "Current Working Directory is: " . cwd;
warn "PATH is: " . join "\n", $ENV{PATH};
my $error = system("cmd.exe /c patt.exe -S $filename");
if ( $error ) {
die qq(Patt failed.);
}
}
1;
Проверьте текущий рабочий каталог по Windows PATH и посмотрите, дает ли это подсказку, почему patt
не выполняется