Forum Webscript.Ru

Программирование => Perl => Тема начата: xmolex от 07 Мая 2008, 17:07:20

Название: open2 для Win
Отправлено: xmolex от 07 Мая 2008, 17:07:20
Здравствуйте. Появилась проблема, которую я не могу решить самостоятельно, поэтому решил обратиться в качестве последней надежды к вам.
Имеется два скрипта. Первый скрипт запускает второй, передает ему во входной поток данные, ждет, когда данные обработаются и потом пытается получить отработанный результат.
Используя IPC::Open2 я добиваюсь нужного результата, но мне нужно, чтобы была мультиплатформенность, а он только на UNIX системах работает. Раньше я решал эту проблему для других систем просто создавав первым скриптом темповый файл, записывал туда данные и запускал второй скрипт с именем файла в параметре. Некрасиво, а что делать? Но тут возникла необходимость ловить данные POST. А это напрямую входной поток. Как я вторым скриптом смогу прочитать данные отправленные методом POST, если у меня там только имя файла. Вообщем, нужно писать во входной поток. Искал решения две недели, но похоже его просто нет. Я просто в отчаянии и в качестве последней надежды решил попросить помощи здесь.
Нашел интересную тему: http://forums.webscript.ru/showthread.php?threadid=25102. В ней советуют использовать конструкцию $text = `1.pl &`; и впринципе такая конструкция могла бы решить проблему, но как после & передать данные? Я могу их ввести только с клавиатуры.
Вообщем, очень жду совета.
Название: open2 для Win
Отправлено: xmolex от 08 Мая 2008, 15:35:48
На данный момент нашел опять таки кривое решение для Win и Mac платформы (возможно и для других, просто нет возможности проверить). Поток который мне нужно направить во вторую программу записываю в файл, например в 1.txt.
А потом выполняю $text = `perl prog2.pl < 1.txt`;
Работает, но всеже хочется отойти от использования промежуточных файлов. Поэтому буду очень благодарен за полезные мысли.
Название: open2 для Win
Отправлено: vladsu от 18 Мая 2008, 04:15:20
Может я чего не понял, тогда объясните, а пока вот:

/tmp/1.pl

#!/usr/bin/perl -w

use strict;

my $feedback = qx(/tmp/2.pl 8 254);

print "Feedback: $feedback\\n";


/tmp/2.pl

#!/usr/bin/perl -w

use strict;

print $ARGV[0] * $ARGV[1];
Название: open2 для Win
Отправлено: xmolex от 20 Мая 2008, 16:53:32
Мне нужно получать не аргументы, а полностью входной поток. К примеру, я хочу первым скриптом принять данные отправленные методом POST и передать их второму.
Название: open2 для Win
Отправлено: vladsu от 20 Мая 2008, 18:02:57
Цитировать
xmolex:
К примеру, я хочу первым скриптом принять данные отправленные методом POST и передать их второму.

И? В чём проблема? Вы приняли первым скриптом данные, в какую-либо переменную/структуру, и хотите передать второму скрипту для дальнейшей обработки, так?
Название: open2 для Win
Отправлено: xmolex от 20 Мая 2008, 23:08:27
Все верно, только мне мультиплатформенность нужна.
Название: open2 для Win
Отправлено: vladsu от 21 Мая 2008, 01:08:25
Цитировать
xmolex:
Все верно, только мне мультиплатформенность нужна.


Так уже хорошо. А теперь я скажу ещё раз: "И"?
То что я Вам привел точно работает на: Linux(RH, SuSE), AIX и Windows(куда же без него) - у меня работает, уверен и на маке работать будет, какие ещё Вам платформы нужны?

Теперь когда мы разобрались с технологией, можно подумать об оптимизации. Дело в том, что данный вариант может подойти к одной задаче, мои запросы, до сих пор, такой вариант удовлетворял, это когда передача идёт до нескольких мегов и на одной машине. А ведь можно всё сделать гораздо универсальней ни от чего не зависимо (объёмов, машин...), только это будет очень навороченно, но с бОльшим контролем - правда работать будет медленней.

Но это всё гадание, сами знаете на чём, т.к. я не знаю Вашу задачу.  В любом случае ответ Вы получили, пробуйте, при конкретизации задачи могу дать более определённые рекомендации.
Название: open2 для Win
Отправлено: xmolex от 29 Мая 2008, 09:55:04
Хорошо. Конкретизирую.
Имеется файл 1.bin. Я хочу его открыть первой программой и передать второй.
##################################
# код первой программы
##################################
#!/usr/bin/perl
open(BIN, "1.bin");
$make = $_ foreach ();
close(BIN);
$feedback = qx(2.pl $make);
print $feedback;

##################################
#  код второй программы
##################################
#!/usr/bin/perl
while (<>) { $temp .= $_; }
if ($temp ne "") {print "OK";} else {print "NO";}

# конец программ
Дело в том, что когда я передаю $make, то это передается и считается командами оболочки, а не входным потоком запускаемой программы. В любом случае, если вы возьмете какой-нибудь avi файл к примеру и попытаетесь передать его, то получите кучу ошибок.
Пояснить командной оболочке, что вы передаете входной поток можно указав символ &, вот только из программы добиться правильного его использования у меня не вышло.
Название: open2 для Win
Отправлено: vladsu от 30 Мая 2008, 02:39:17
Хочется выругаться - выругаюсь кодом

/tmp/1.pl

#!/usr/local/bin/perl -w

use strict;

my $make;

open(BIN, "/tmp/3.bin"); # 3.bin - это мультик Шрек в ави размером 700М

$make .= \'"\';  # Одиночная, двойная и опять одиночная
while ( ) {
   $make .= $_;
}
$make .= \'"\'; # Тоже что и выше

close(BIN);

my $feedback = qx(/tmp/2.pl $make);

print $feedback,"\\n";



/tmp/2.pl

#!/usr/bin/perl -w

use strict;

my $temp;

$temp = $ARGV[0];
if ($temp ne "") {print "OK";} else {print "NO";}


Результат:
/tmp> time ./1.pl
OK

real    0m12.555s
user    0m7.964s
sys     0m3.036s


Надеюсь при необходимости первый и последний байт отрезать сумеете? Те самые добавленные кавычки.
Название: open2 для Win
Отправлено: xmolex от 30 Мая 2008, 08:25:17
Хм, зачем ругаться? Если вы про не использование прагмы strict или про не объявление переменных, так это сделано для уменьшения сообщений на форуме, просто чтобы отобразить суть.
Что касается вашего примера, то он работоспособен, но лично у меня он не сработал до конца.
Попробуйте передать текстовый файл, где существуют переходы строки и символы " (двойной кавычки). Лично на win платформе у меня передалась только первая строка.
Название: open2 для Win
Отправлено: vladsu от 30 Мая 2008, 12:10:18
А догадаться экранировать кавычки?


#!/usr/local/bin/perl -w

use strict;

my $make;

open(BIN, "/tmp/3.bin");

$make .= \'"\';
while ( ) {
   s/(\'|")/\\\\$1/g;
   $make .= $_;
}
$make .= \'"\';

close(BIN);
my $feedback = qx(/tmp/2.pl $make);
print $feedback,"\\n";



use strict;

$ARGV[0] =~ s/\\\\(\'|")/$1/g;
print length $ARGV[0];
Название: open2 для Win
Отправлено: xmolex от 30 Мая 2008, 14:45:06
Понимаете, дело в том, что мне нужно передать поток так, чтобы его потом не нужно было обрабатывать вторым скриптом.
Вообще, задача стоит следующая:
Есть скрипт человека. Есть мой скрипт. Веб сервер запускает мой скрипт, мой скрипт ловит переменные окружения. Мой скрипт получает данные от браузера (GET или POST). Мой скрипт переводит данные в POST, добавляя свои данные. Потом весь этот сформированный пакет я посылаю скрипту человека, не забывая подправить переменные окружения под метод POST. Тоесть я своим скриптом запускаю скрипт человека и во входной поток посылаю мой сформированный POST пакет, а человек уже работает с данными, как буд-то получил данные методом POST.

P.S. в моем файле кавычек не было, он так на переход строки среагировал.