LinuxForum.Fans
Тема

[Perl] писать -> программа -> файл

Автор: AndreyMust19 5 сообщений 2277 просмотров
#82053

Надо отсортировать список файлов - вызвать внешнюю программу sort, на вход подать список файлов, а с выхода записать отсортированный список в файл.
Не хочу создавать кучу временных файлов:

text
print `sort file`;

, а писать прямо на вход программы sort.

Пробовал:

text
open(SORT, "|sort");

Так вот, выходной файл либо оказывается пустым, потому что программа sort вызывается только после закрытия дескриптора и весь результат ее работы почему-то выводится на экран). Пробовал pipe и запись в переменную, все равно выходной файл остается пустой.

text
#!/usr/bin/perl
$dir='/';
if ($ARGV[0]) {        # если есть первый аргумент
    $dir=`realpath $ARGV[0]`;
    chomp $dir;
};
$listfiles=`mktemp /tmp/file.XXX`; chomp $listfiles;
open(FILES,"> $listfiles");# || die;
# сортировка списка файлов

open(SORT, "|sort|");# || die; #open($f1, '>', \$variable); until (eof `find $dir`) { print SORT `find $dir`}; until (eof SORT) { print FILES <SORT>; };

#pipe(`find $dir`,SORT); #pipe(SORT,FILES);

#print SORT `cat /home/andrey/proba_files`; #@s = `find $dir`; #print SORT @s; #print SORT `find $dir`; #close SORT; #until (eof SORT) { print FILES <SORT>; }; #close(FILES);

print "dir = $dir, listfiles = $listfiles\n";

#84116

Пока проблема не решена, обшелся созданием еще одного временного файла.
Нельзя ли создать временный файл в памяти, а не на диске?

#84149

не знаю перла, но точно знаю, там есть функция system, которая вызывает внешние системные функции. не оно?

#84175

Она просто запускает дочерний процесс. Мне же надо передать данные на вход stdin.
Хотя, возможно, получится создать pipe, а потом создать дочерний процесс, может он эти pipe наследует.

#89124

there is more than one way to do it...
1. Самое простое: использовать модуль IPC::Open2
2. Самое эффективное, как утверждает perldoc: использовать socketpair + fork + exec
3. И еще вариантик: создать 2 pipe для чтения и записи, затем fork, в дочернем процессе переоткрыть STDOUT в канал открытый pipe и сделать exec. Так собственно и работает модуль IPC::Open2, только делает всю грязную работу за вас

А вообще читайте perldoc perlipc, там всё это есть.

Войдите или зарегистрируйтесь, чтобы ответить.