Вы задали удивительно сложный вопрос. Вы хотите запустить внешнюю команду (cp
), в то же время продолжая выполнение программы Perl (производя информацию о ходе выполнения). Другими словами, они оба выполняются одновременно.
Классическим способом сделать это является выполнение внешней команды в отдельном процессе и вывод обновлений в ожидании завершения этого процесса.
Первая часть обычно выполняется fork
процессом. Это легко понять неправильно, поэтому я предлагаю использовать Proc :: Fork .
Вторая часть требует некоторой утонченности, так как вам нужно сидеть сложа руки и ждать окончания процесса, но время от времени нужно что-то выводить, но не нужно заняты - ждать и записывать циклы процессора. Самый безопасный способ сделать это - это спать между выходами. Для этого я рекомендую Time :: HiRes (который является частью стандартного дистрибутива Perl).
И вот код:
use strict;
use warnings;
use English; # for more mnemonic special variable names
use POSIX ":sys_wait_h";
use Proc::Fork;
use Time::HiRes qw( usleep );
run_fork {
child {
exec q[sleep 3];
}
parent {
my $child_pid = shift;
my $pid;
my $loop;
STDOUT->autoflush;
while ( 0 == ($pid = waitpid $child_pid, WNOHANG ) ){
print '.';
++$loop;
usleep(5000);
}
print "\n" if $loop;
# for more complete handlng of $CHILD_ERROR, see the
# documentation for the perl system function
die( "error in child process\n" ) if $CHILD_ERROR;
}
};
Если вам нужны необычные индикаторы выполнения, взгляните на Term :: ProgressBar