Поскольку на самом деле нет никакого способа программно отслеживать ход выполнения rsync, я думаю, что вам лучше всего "прокрутить" вывод и попытаться как-то "угадать" его прогресс.
Первое, что вы должны сделать, это использовать subprocess
вместо commands.getstatusoutput
, потому что вы получите гораздо больший контроль над выводом с экрана stdout rsync для отслеживания его прогресса.Одним из решений может быть выполнение rsync с опцией -v
, которая будет печатать каждый переданный файл с последующим переводом строки (плюс некоторые другие ненужные слова).Простой способ догадаться о прогрессе rsync заключается в следующем:
import subprocess
p = subprocess.Popen(['rsync', '-v', ..other rsync args..], shell=True,
stdout=subprocess.PIPE, close_fds=True)
while p.stdout.readline():
...
# rsync has just "completed" an operation, i.e. it probably
# transferred a file. now would be a good time to update the
# ProgressBar. there are some options here, see below...
...
ret = p.wait()
print "Rsync exited with code %d" % ret
Это читает вывод rsync -v ...
по одной строке за раз, и в цикле while
выобновит ProgressBar
в зависимости от ситуации.Тогда возникает вопрос, что за обновление?ProgressBar
на самом деле имеет два режима - один, который «пингует» взад и вперед, указывая на прогресс в направлении какой-то неопределенной цели, и другой, который перемещает полосу слева направо на основе приращения к известной цели.
Вы можетепопытайтесь «угадать» количество файлов, которые rsync передаст, предварительно получив список файлов (с --list-only
или -vn
), и используйте это в качестве цели, но это по своей природе подвержено ошибкам, поскольку вы рискуетеСписок файлов отправителя изменяется между моментом его сбора и фактическим выполнением rsync.Лучшее решение, вероятно, состоит в том, чтобы просто вызвать pulse()
на ProgressBar
в цикле while
, чтобы указать, что вещи происходят в фоновом режиме.Если вы хотите отобразить дополнительную информацию, вы можете прочитать вывод p.stdout.readline()
и обновить gtk.Label
где-нибудь, чтобы указать, какие файлы передаются.
(Примечание: приведенный выше код не учитываетусловия ошибки при выполнении rsync, что вам, вероятно, следует сделать)