python скопировать файл в локальную сеть (linux - ›linux) и вывести

Я пытаюсь написать сценарий для копирования файлов на моем RaspberryPi с моего настольного ПК. Вот мой код: (часть)

print "start the copy"   
path_pi = '//192.168.2.2:22/home/pi/Stock/'
file_pc = path_file + "/" + file
print "the file to copy is: ", file_pc

shutil.copy2(file_pc, path_pi + file_pi)

На самом деле у меня такая ошибка: (на французском)

IOError: [Errno 2] Aucun fichier ou dossier de ce type: '//192.168.2.2:22/home/pi/Stock/exemple.txt'

Итак, как я мог продолжить? Должен ли я подключить 2 машины перед копированием? Я пробовал:

path_pi = r'//192.168.2.2:22/home/pi/Stock'

Но проблема та же. (И file_pc - это переменная)

Спасибо

Изменить: Хорошо, я нашел это:

command = 'scp', file_pc, file_pi  
p = subprocess.Popen(command, stdout=subprocess.PIPE) 

Но нет возможности получить вывод ... (работать с Shell = False)


person Guillaume    schedule 27.03.2014    source источник


Ответы (2)


shutil.copy2() работает с локальными файлами. 192.168.2.2:22 предлагает скопировать файлы по ssh. Вы можете смонтировать удаленный каталог (RaspberryPi) в локальный каталог на вашем настольном компьютере (sshfs), чтобы shutil.copy2() работал.

Если вы хотите увидеть вывод команды, не устанавливайте stdout=PIPE (примечание: если вы устанавливаете stdout=PIPE, вы должны читать из p.stdout, иначе процесс может заблокироваться навсегда):

from subprocess import check_call

check_call(['scp', file_pc, file_pi])

scp будет печатать туда, куда печатает ваш родительский скрипт Python.

Чтобы получить вывод в виде строки:

from subprocess import check_output

output = check_output(['scp', file_pc, file_pi])

Хотя похоже, что scp по умолчанию ничего не печатает, если вывод перенаправлен.

Вы можете использовать pexpect, чтобы scp думали, что он работает в терминале:

import pipes
import re
import pexpect # $ pip install pexpect

def progress(locals):
    # extract percents
    print(int(re.search(br'(\d+)%[^%]*$', locals['child'].after).group(1)))

command = "scp %s %s" % tuple(map(pipes.quote, [file_pc, file_pi]))
status = pexpect.run(command, events={r'\d+%': progress}, withexitstatus=1)[1]
print("Exit status %d" % status)
person jfs    schedule 27.03.2014
comment
Спасибо, все нормально работает. Как я могу получить обратный вызов в виде строки? - person Guillaume; 27.03.2014
comment
@Guillaume: я обновил ответ, чтобы показать, как получить вывод подпроцесса - person jfs; 27.03.2014
comment
Хорошо, но: out = check_output (['scp', file_pc, file_pi]) распечатать Ничего не видно, остается в первой строке. Фактически, я хотел бы получить процент для индикатора выполнения - person Guillaume; 27.03.2014
comment
@Guillaume: обновите свой вопрос или спросите новый конкретно о том, как получить процент от команды scp. - person jfs; 27.03.2014
comment
@Guillaume: Я добавил решение на основе pexpect, которое может извлекать информацию о прогрессе из scp - person jfs; 28.03.2014
comment
Спасибо за вашу помощь, но я попытаюсь импортировать модуль paramiko, он кажется более простым в использовании. - person Guillaume; 28.03.2014
comment
@Guillaume: попробуйте fabric, он построен поверх paramiko. См. Как скопировать каталог на удаленный компьютер с помощью Fabric?. кстати, сомневаюсь, что paramiko код проще, чем pexpect. Вот пример кода загрузки с использованием paramiko. - person jfs; 28.03.2014
comment
Я задал новый вопрос с модулем paramiko, потому что это почти успешно. Что касается ткани, я еще не тестировал. - person Guillaume; 28.03.2014
comment
Решение pexpect работает нормально. Прогресс def (локальный) должен быть помещен в другой def (self, data). - person Guillaume; 28.03.2014

У вас включен SSH? Что-то вроде этого могло бы вам помочь:

import os
os.system("scp FILE USER@SERVER:PATH")
person PabloRosales    schedule 27.03.2014
comment
Хотя это должно сработать, это не очень хорошая идея. Использование subprocess.call(['scp', filename, '{}@{}:{}'.format(user, hostname, path)]) было бы немного чище. os.system создает оболочку и оценивает текст, что и не нужно, и может привести к легким уязвимостям безопасности, если вы вводите какие-либо данные пользователя в это поле. - person wolfd; 25.08.2017