Одним из способов является настройка терминальной среды для процесса, псевдотерминала (pty).Это трудно сделать правильно и очень зависит от системы, но IPC :: Run имеет эту возможность, готовую к простому использованию.
Вот драйвер, работающий с использованием at
, так чтоон не имеет управляющего терминала (или запускает его через cron
)
use warnings;
use strict;
use feature 'say';
use IPC::Run qw(run);
my @cmd = qw(./t_term.pl input arguments);
run \@cmd, '>pty>', sub { say "out: @_" };
#run \@cmd, '>', sub { say "out: @_" } # no pty
При >pty>
он устанавливает псевдотерминал для STDOUT
программы в @cmd
(это канал с>
);также см. <pty<
и подробнее о перенаправлении .Анонимный sub {}
вызывается каждый раз, когда выводится дочерний процесс, поэтому его можно обрабатывать по ходу дела.Для этого есть и другие варианты.
Программа, которая называется (t_term.pl
), тестирует только для терминала
use warnings;
use strict;
use feature 'say';
say "Is STDOUT filehandle attached to a terminal: ",
( (-t STDOUT) ? "yes" : "no" );
sleep 2;
say "bye from $$";
-t STDOUT
(см. операторы filetest) является подходящим способом проверки терминала в этом примере.Подробнее / другие способы см. в этом посте .
. Вывод показывает, что вызываемая программа (t_term.pl
) видит терминал на своем STDOUT
, даже если драйвер работает без такового.(используя at
или когда закончится crontab
).Если >pty>
изменяется на обычное перенаправление с помощью >
(с использованием канала), то терминала нет.
Решает ли это проблему с буферизацией, явно зависит от этой программы, и достаточно ли этогообмануть его с помощью терминала.
Другой способ решения этой проблемы - использовать unbuffer
, когда это возможно, как в ответе моба.