Я должен выполнить строку через программу Java и затем получить вывод. Программа Java принимает строку через стандартный вход. Следующие работы:
my $output = `echo $string | java -jar java_program.jar`;
Существует одна проблема: $string
могло быть примерно что-либо. Какие-либо мысли о хорошем решении этой проблемы?
Предлагаю вам посмотреть модуль IPC :: Run3
. Он использует очень простой интерфейс и позволяет получить STDERR
и STDOUT
. Вот небольшой пример:
use IPC::Run3;
## store command output here
my ($cmd_out, $cmd_err);
my $cmd_input = "put your input string here";
run3([ 'java', '-jar', 'java_program.jar'], \$cmd_input, \$cmd_out, \$cmd_err);
print "command output [$cmd_out] error [$cmd_err]\n";
См. IPC :: Run3
сравнение с другими модулями .
Если вы можете использовать модули CPAN (а я предполагаю, что большинство людей могут), посмотрите ответ Ивана об использовании IPC :: Run3 . Он должен обрабатывать все, что вам нужно.
Если вы не можете использовать модули, вот как это сделать обычным способом.
Вы можете использовать конвейер для ввода данных, и это позволит избежать всех этих цитирований командной строки issues:
open PIPE, "| java -jar java_program.jar";
print PIPE "$string";
close(PIPE);
Похоже, вам действительно нужен вывод команды. Вы могли открыть два канала с помощью чего-то вроде IPC :: Open2 (в и из java-процесса), но вы рискуете попасть в тупик, пытаясь иметь дело с обоими каналами одновременно.
Этого можно избежать, если вывести java-файл в файл, а затем читать из этого файла:
open PIPE, "| java -jar java_program.jar > output.txt";
print PIPE "$string";
close(PIPE);
open OUTPUT, "output.txt";
while (my $line = <OUTPUT>) {
# do something with $line
}
close(OUTPUT);
Другой вариант - сделать все наоборот. Поместите $ string во временный файл, затем используйте его как входные данные для java:
open INPUT, "input.txt";
print INPUT "$string";
close(INPUT);
open OUTPUT, "java -jar java_program.jar < input.txt |";
while (my $line = <OUTPUT>) {
# do something with the output
}
close(OUTPUT);
Обратите внимание, что это не лучший способ создания временных файлов; Я только что использовал output.txt
и input.txt
для простоты. Прочтите File :: Temp docs , чтобы узнать о различных способах более чистого создания временных файлов.
Вы изучали IPC :: Run
?
Возможно, вы ищете синтаксис, подобный этому:
use IPC::Run qw( run );
my $input = $string;
my ($out, $err);
run ["java -jar java_program.jar"], \$input, \$out, \$err;
Создайте конвейер просто как и ваша оболочка.
Вот наша страшная строка:
my $str = "foo * ~ bar \0 baz *";
Мы построим конвейер в обратном направлении, поэтому сначала мы соберем выходные данные программы Java:
my $pid1 = open my $fh1, "-|";
die "$0: fork: $!" unless defined $pid1;
if ($pid1) {
# grab output from Java program
while (<$fh1>) {
chomp;
my @c = unpack "C*" => $_;
print "$_\n => @c\n";
}
}
Обратите внимание на специальный "- |"
для оператора Perl open
.
Если вы открываете канал по команде
'-'
, т.е. , либо'| -'
или'- |'
Встроенный модуль IPC :: Open2 предоставляет функцию для обработки двунаправленных каналов без внешнего файла.