Как я могу получить сообщения о прогрессе rsync в Perl? - PullRequest
2 голосов
/ 23 марта 2009

Я хочу захватить все сообщения о прогрессе, генерируемые процессом rsync, из сценария Perl. В определенных обстоятельствах это не работает.

Вот типичная командная строка rsync, которую я использую:

rsync -aL --verbose --progress --bwlimit=100 \
  --include-from=/tmp/78hJ2eDCs1 \
  --include '*/' --exclude '*' \
  /srcdir/* \
  hostname:/target/ 2>&1

Если я выполню это в оболочке bash, я увижу что-то вроде этого:

Building file list ...
1600 files...
1700 files...
and so on

Если я попробую ту же команду в Perl, я получу вывод «Список строящихся файлов» в порядке, но не обновлю статус. Вот как я тестирую захват

my $pid = open(OUTPUT, "$cmd |")  or die "Couldn't fork: $!\n";

my $ch;
while(read(OUTPUT, $ch, 1)==1)
{
    print $ch;
}
close(OUTPUT);

Я предполагаю, что rsync чувствует, что дескриптор вывода не является типичной консолью, или выводится каким-то необычным образом, который я не собираю Однако, что еще более странно, так это то, что если я опущу фильтры --include и --exclude, я смогу перехватить сообщения о состоянии просто отлично. Кто-нибудь знает, что происходит?

Ответы [ 5 ]

4 голосов
/ 23 марта 2009

вы можете использовать Expect.pm , который имитирует PTY, что может дать вам искомый выход.

Если этого не сделать, вы можете попробовать варианты --stats или --progress.

4 голосов
/ 23 марта 2009

Perl буферизует вывод из каналов? Если это так, возможно, вы сможете заставить его работать, если после открытия дескриптора OUTPUT вы отключите буферизацию с помощью OUTPUT-> autoflush (1);

3 голосов
/ 23 марта 2009

Оказывается, решение было простым - мне просто пришлось отменить буфер ввода-вывода в моем скрипте с помощью $| = 1;

Я все еще озадачен тем, как я наблюдал проблему с некоторыми опциями rsync, а не с другими. Спасибо Пол Томблин и DSM за предоставленные мне идеи.

0 голосов
/ 31 июля 2009

Страдание от буферизации? - лучшее объяснение эффекта буферизации, которое я нашел до сих пор. Стоит потратить время на прочтение и понимание.

Не забывайте, что буферизация существует по какой-то причине, поэтому не просто слепо отключайте ее для каждой возможной проблемы.

0 голосов
/ 23 марта 2009

Возможно, вы также захотите использовать IPC :: Run и его обратные вызовы для данных в stdout / stderr.

...