LINUX.ORG.RU
решено ФорумAdmin

perl выполнение внешних программ

 


0

2

Добрый день, потребовалось читать вывод программы, запускаю через perl, не работает, не чего вы выдаёт.

open my $a, "/usr/local/bin/ices -c /etc/ices/ices.conf |";
 while (my $line = <$a>) { # читаем
    print $line;
 }
 close $a; # закрываем выходной поток

Помогите разобраться что делаю не так.

А вы вообще пробовали запускать /usr/local/bin/ices -c /etc/ices/ices.conf ?
И ожидаемое не на stderr уходит?

anc ★★★★★ ()
Ответ на: комментарий от anc
 root@spam:/home/mannaz# /usr/local/bin/ices -c /etc/ices/ices.conf
Logfile opened
Playing /home/mannaz/mu/mp3/1299__-Toyota_Vitz.mp3
Mounted on http://localhost:8000/ices
^CIces Exiting...

stderr или stdout, проверял так

Запускаю

root@spam:/home/mannaz# /usr/local/bin/ices -c /etc/ices/ices.conf 1>1
root@spam:/home/mannaz# /usr/local/bin/ices -c /etc/ices/ices.conf 2>2
После этого в «1»
Logfile opened
Playing /home/mannaz/mu/mp3/1299__-Toyota_Vitz.mp3
Mounted on http://localhost:8000/ices
Ices Exiting...
в 2, пусто. Предполагаю что работает оно в stdout, но могу и ошибаться, поправите если не прав.

mannaz2004 ()
Последнее исправление: mannaz2004 (всего исправлений: 1)

а зачем вертикальная черта в конце строки вызова внешней программы?

open my $a, "/usr/local/bin/ices -c /etc/ices/ices.conf |";

bvn13 ★★★★★ ()
Ответ на: комментарий от bvn13

Ну если верить документации на Perl, если | стоит перед вызываемой программы то мы будем отправлять в поток, а если после команды то получать из потока.

mannaz2004 ()
Ответ на: комментарий от mannaz2004

For three or more arguments if MODE is |- , the filename is interpreted as a command to which output is to be piped, and if MODE is -| , the filename is interpreted as a command that pipes output to us

false ★★★★★ ()
Ответ на: комментарий от false

Здрасте, у меня выхлоп /usr/local/bin/ices это 100500 миллионов строк. Че все в память грузить и только потом обрабатывать? Не, нам такой хок perl не нужен

anonymous ()
Ответ на: комментарий от anonymous

Ну так вам же это не понравилось. Я предложил другой вариант. По open3 замечания есть? Хотелось бы узнать ваше экспертное мнение.

Bad_ptr ★★★★ ()
Последнее исправление: Bad_ptr (всего исправлений: 1)
Ответ на: комментарий от Bad_ptr

Мне не понравилось, да. Я указал товарищу ущербность его решения. НО!!! я не просил решения, оно мне известно. Так что, дружок, вали со своим ЧСВ в детсад, будешь там пальцы гнуть,

anonymous ()
Ответ на: комментарий от Bad_ptr

Обращайся если еще что не понятно.

open3() does not wait for and reap the child process after it exits. Except for short programs where it's acceptable to let the operating system take care of this, you need to do this yourself. This is normally as simple as calling «waitpid $pid, 0» when you're done with the process. Failing to do this can result in an accumulation of defunct or «zombie» processes. See «waitpid» in perlfunc for more information.

If you try to read from the child's stdout writer and their stderr writer, you'll have problems with blocking, which means you'll want to use select() or the IO::Select, which means you'd best use sysread() instead of readline() for normal stuff.

This is very dangerous, as you may block forever. It assumes it's going to talk to something like bc, both writing to it and reading from it. This is presumably safe because you «know» that commands like bc will read a line at a time and output a line at a time. Programs like sort that read their entire input stream first, however, are quite apt to cause deadlock.

The big problem with this approach is that if you don't have control over source code being run in the child process, you can't control what it does with pipe buffering. Thus you can't just open a pipe to «cat -v» and continually read and write a line from it.

anonymous ()

Твой код работает, замени команду на date и убедись. Проблема в том, что вызываешь. Может эта программа переменную окружения хочет, может вывод на терминал, нужно смотреть её ман или код

disarmer ★★★ ()
Последнее исправление: disarmer (всего исправлений: 1)
Ответ на: комментарий от disarmer

Я знаю что мой код рабочий я его проверил подставил вместо «/usr/local/bin/ices -c /etc/ices/ices.conf |» поставил «ls», всё работает, это я ещё до написания на форум проверил. Программа то запускается и работает как надо, но при этом молчит. Аж противно, «школьник», а ты видать родился умным сразу.

mannaz2004 ()
Последнее исправление: mannaz2004 (всего исправлений: 1)
Ответ на: комментарий от mannaz2004

Программа то запускается и работает как надо, но при этом молчит.

Некоторые проги умею детектить запущены ли они в терминале или через пайп. Может в этом проблема

Bad_ptr ★★★★ ()
Ответ на: комментарий от mannaz2004

Ну теоретически надо подсунуть псевдотерминал. В perldoc -ri Open2 упоменаются IO::Pty и Expect.

Bad_ptr ★★★★ ()
Ответ на: комментарий от disarmer

Не смотри в зеркало и школоты не увидишь

anonymous ()
Ответ на: комментарий от mannaz2004

Аж противно,

Как будто школьник это что-то плохое. Извини, по цифрам в нике и грамматике показалось.

Программа то запускается и работает как надо, но при этом молчит

Так она у тебя не сразу завершается, как ls? Тогда это скорее всего буферизация, в лучшем случае лечится так:

$|=1;

disarmer ★★★ ()
Ответ на: комментарий от mannaz2004

Думаю, что речь шла о чем-то таком

open my $a, "/usr/local/bin/ices -c /etc/ices/ices.conf |" || die "pisec";

anc ★★★★★ ()
Ответ на: комментарий от mannaz2004

Аж противно, «школьник», а ты видать родился умным сразу.

Ладно, школьник, учись пока я жив. То, что приведено в шапке — типичный говнокод. Тебе тут уже два человека сказали: проверяй на ошибки. Я же добавлю:

(1) Проверяй не только открытие файла, а любую операцию, которая может завершиться неуспешно. Хотя бы закрытие файла. (А я бы проверял и чтение тоже.)

(2) Выводи *нормальные* сообщения об ошбках. die «pisec» — лучше чем ничего, но всё равно фигово. Пиши:

die "can't open что-ты-там-открываешь: $!\n";

Обрати внимание на $!.

(3) Открой для себя прагмы:

use warnings; 
use strict;
use autodie ':all'; 

эти как минимум.

(4) Открой для себя модули и metacpan.org. В данном случае могли бы пригодиться IPC::System::Simple или IPC::Run3 — выбирай на свой вкус. (В принципе, autodie уже делает большую часть работы; IPC::Run3 можно попользовать если нужно что-нить дополнительно — перехватить stderr, записать что-нить в stdin, etc.)

(5) В случае непоняток кури маны. Перловые маны *очень* хороши. Кури их на английском языке, не кури кривые и устаревшие переводы на русский.

(6) Не знаешь английский? Займись им.

Будешь выполнять сии пункты — постепенно станешь умным. Будешь делать всё тяп-ляп, на скорую руку — так и останешься говнокодером независимо от возраста.

debugger ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.