У меня есть сценарий Perl, который использует внешний инструмент (cleartool) для сбора информации о списке файлов. Я хочу использовать IPC, чтобы не создавать новый процесс для каждого файла:
use IPC::Open2;
my ($cin, $cout);
my $child = open2($cout, $cin, 'cleartool');
Команды, которые возвращают одну строку, работают хорошо. например
print $cin "describe -short $file\n";
my $description = <$cout>;
Команды, которые возвращают несколько строк, ставят меня в тупик, как использовать весь ответ, не зависая из-за блокирующего чтения:
print $cin "lshistory $file\n";
# read and process $cout...
Я попытался установить дескриптор файла для неблокирующего чтения через fcntl
:
use Fcntl;
my $flags = '';
fcntl($cout, F_GETFL, $flags);
$flags |= O_NONBLOCK;
fcntl($cout, F_SETFL, $flags);
но Fcntl умирает с сообщением «Ваш поставщик не определил макрос Fcntl F_GETFL».
Я пытался использовать IO::Handle для установки $cout->blocking(0)
, но это не помогло (он возвращает undef
и устанавливает $!
в "Неизвестная ошибка").
Я пытался использовать select
, чтобы определить, доступны ли данные, прежде чем пытаться читать:
my $rfd = '';
vec($rfd, fileno($cout), 1) = 1;
while (select($rfd, undef, undef, 0) >= 0) {
my $n = read($cout, $buffer, 1024);
print "Read $n bytes\n";
# do something with $buffer...
}
но это зависает, даже ничего не читая. Кто-нибудь знает, как заставить это работать (в Windows)?