Perl: данные -> программа -> вывод

Тема в разделе "WASM.UNIX", создана пользователем AndreyMust19, 1 окт 2010.

  1. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Нужно запустить внешнюю программу так, чтобы можно было послать ей на вход данные и прочитать данные с выхода.
    Как в sh:
    Код (Text):
    1. $ sort <list >result
    Нужно отсортировать по имени список файлов (это делает программа sort). Не хочу создавать временный файл со списком, а хочу сразу посылать его на вход sort.
    Обрат. кавыки возвращают только вывод команды в массиве:
    Код (Text):
    1. `sort`
    Понял, что так:
    Код (Text):
    1. open(FN, "| sort |")
    - нельзя, запрещается открывать open'ом сразу 2 конвейера.

    Подходящие варианты:
    Код (Text):
    1. use FileHandle;
    2. use IPC::Open2;
    3. $pid = open2(*Reader, *Writer, "cat -u -n" );
    4. print Writer "stuff\n";
    5. $got = <Reader>;
    Или создание 2-х pipe'ов:
    Код (Text):
    1. pipe(PARENT_RDR, CHILD_WTR);
    2. pipe(CHILD_RDR, PARENT_WTR);
    3. CHILD_WTR->autoflush(1);
    4. PARENT_WTR->autoflush(1);
    и порождение дочернего процесса:
    Код (Text):
    1. if ($pid = fork) {
    2.     # parent
    3.     close PARENT_RDR; close PARENT_WTR;
    4. ...
    5. } else {
    6.     # child
    7.     close CHILD_RDR; close CHILD_WTR;
    который сделает перенаправление дескрипторов pipe на STDIN и STDOUT и вызовет system('sort') или сделает open2.
    К сожалению, оба варианта не работают (программа не отвечает и ничего не выводит на экран). Буферизацию отключаю:
    Код (Text):
    1. select((select(STDIN), $|=1)[0]);
    2. select((select(STDOUT), $|=1)[0]);
    или
    Код (Text):
    1. use IO::Handle;
    2. ...
    3. CHILD_WTR->autoflush(1);
    4. PARENT_WTR->autoflush(1);
     
  2. pivikov

    pivikov New Member

    Публикаций:
    0
    Регистрация:
    19 сен 2010
    Сообщения:
    19
    Примеры из книги "Perl сборник рецептов", возможно помогут.
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    AndreyMust19
    Выбрось этот язык, изучай Python он ща во все и вся залез, даже в WinDbg в виде PyDbg
     
  4. Kaimi

    Kaimi Андрей

    Публикаций:
    0
    Регистрация:
    15 апр 2010
    Сообщения:
    120
    Не совсем понятно что ты хочешь. sort же по-идее на вход принимает имя файла и в то же время ты не хочешь создавать временный файл. И почему обязательно вызывать sort, если можно отсортировать перлом или там большой объем данных?
     
  5. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Kaimi
    Это *nix, сынок. =)
    sort, будучи запущенна без аргументов, читает входные данные из stdin, и пишет отсортированные в stdout. stdin и stdout возможно перенаправить, чтобы напрямую соединить sort с другим процессом. В качестве примера:
    Код (Text):
    1. du -x . | sort -n | tail
    Этой командой я пользуюсь, когда мне очень хочется освободить место на диске, и я не знаю что удалить.
     
  6. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    pivikov
    Спасибо, сам пользуюсь этой книгой.
    EvilsInterrupt
    То же самое говорят поклонники Perl'а тем, кто программирует на Python. Не надо говорить "выбрось", говорите "попробуйте".
    r90
    Спасибо, это помогло. Но как сделать тоже самое пайпами с файловыми дескрипторами?