Найти - Пользователи
Полная версия: subprocess.run не ждет завершения процесса rsync
Начало » Python для новичков » subprocess.run не ждет завершения процесса rsync
1 2
Ematten
Всем привет.
Я, видимо, чего-то не понимаю или упускаю. Вот официальная дока на subprocess.run - https://docs.python.org/3/library/subprocess.html

Цитата из описания

Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.

Я не эксперт в английском, но написано, что ЖДЕТ выполнения.

У меня есть скрипт, который дергает системный rsync. Упростил его немного.

 #!/usr/bin/env python3
import subprocess
def rsync():
    subprocess.run(['rsync', '-ahv', '/path1/', '/path2/'])
print('Start')
rsync()
print('Finish')
Если в /path1 немного файлов, то все ок. Я вижу в выхлопе в терминале Start, потом все, что пишет rsync, потом Finish. Однако если в /path1 файлов хотя бы секунд на 10 копирования, то я вижу, что Finish в выхлопе в середине работы rsync. После Finish еще много файлов копируется, причем это именно копирование rsync, а не сброс кеша из памяти.

В чем проблема? Почему subprocess.run на самом деле не ждет завершения rsync?
ZerG
Так функция выполнила поставленную задачу и код выпоняется дальше
Вы же не указали нигде дополнительного поведения
Если нужен якорь то гляньте эти примеры

 import subprocess
# start the subprocess
process = subprocess.Popen(['ls', '-l'])
# wait for the subprocess to complete
process.wait()
# continue with the rest of your program
print("Subprocess completed.")

или
 import subprocess
# start the subprocess
process = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for the subprocess to complete and collect its output
output, error = process.communicate()
# print the output and any errors
print(output)
print(error)
Ematten
Ни тот, ни другой вариант не работают, точнее, они работают ровно так же, как subprocess.run.

 #!/usr/bin/env python3
import subprocess
def rsync():
    proc = subprocess.Popen(['rsync', '-ahv', '/path1/', '/path2/'])
    proc.wait()
print('Start')
rsync()
print('Finish')

Start
...
syncthing/
syncthing/cert.pem
syncthing/config.xml
syncthing/csrftokens.txt
syncthing/https-cert.pem
syncthing/https-key.pem
syncthing/key.pem
Finish
syncthing/index-v0.14.0.db/
syncthing/index-v0.14.0.db/000040.ldb
syncthing/index-v0.14.0.db/000041.log
syncthing/index-v0.14.0.db/000043.ldb
syncthing/index-v0.14.0.db/CURRENT
syncthing/index-v0.14.0.db/CURRENT.bak
syncthing/index-v0.14.0.db/LOCK
syncthing/index-v0.14.0.db/LOG
syncthing/index-v0.14.0.db/MANIFEST-000042
...
py.user.next
Ematten
Я, видимо, чего-то не понимаю или упускаю.
https://serverfault.com/questions/547165/why-does-rsync-spawn-multiple-processes-for-me

Это особенность rsync какая-то. Так что можешь просто использовать другую программу для копирования файлов и всё будет ровно.
Ematten
Вот оно что. Я и не подумал со стороны rsync взгляднуть на проблему.

Так что можешь просто использовать другую программу для копирования файлов и всё будет ровно.

Других вариантов для меня, увы, нет.
ZerG
Возможно нужно попробовать любу
https://github.com/gchamon/sysrsync

С другой стороны тот же пинг отрабатывает корректно
 import subprocess
def rsync():
    proc = subprocess.Popen(["ping", "-c", "4", "8.8.8.8"])
    proc.wait()
print("Start")
rsync()
print("Finish")


Start
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=118 time=18.015 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=18.106 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=18.665 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=16.818 ms

— 8.8.8.8 ping statistics —
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.818/17.901/18.665/0.673 ms
Finish

попробуй с ключами поиграться - например добавь
–progress

py.user.next
Ematten
Других вариантов для меня, увы, нет.
Ну, если бы rsync не сущестовала, то ты бы вообще не смог скопировать это?
Ematten
py.user.next, скрипт делает бэкап 12 Тб информации в мелких файлах на локальные диски и по сети через ssh. Благодаря тому, что rsync умеет отслеживать изменения перед копированием, это существенно ускоряет процесс и снижает расход трафика. Так что если бы rsync не было (вообще, вопрос странный), надо было бы его придумать.

ZerG, спасибо посмотрю sysrsync. Ключи rsync никак не влияют на проблему. Выше правильно дали ссылку. В rsync захардкожен многопоток, так что как только один поток, который subprocess считает основным, завершается, скрипт продолжает выполнять следующие директивы.
ZerG
немного странно - может вы выполняете скрипт внутри какого-то потока? ССШ или там Tmux?
Я только что запустил по вашему же примеру синкопой локально у себя на машине и все отрабатывает так же как и с пингом
Ematten
немного странно - может вы выполняете скрипт внутри какого-то потока? ССШ или там Tmux?

Запускаю локально в терминале без мультиплексеров.

Я только что запустил по вашему же примеру синкопой локально у себя на машине и все отрабатывает так же как и с пингом

Условия проверки, которые я выше описывал, соблюдены? Копирование больше 10 секунд?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB