Как scp в Python?
Какой самый питонный способ scp файла в Python? Единственный маршрут, о котором я знаю, это
os.system('scp "%s" "%s:%s"' % (localfile, remotehost, remotefile) )
который является хаком, и который не работает вне Linux-подобных систем, и который нуждается в помощи от модуля Pexpect, чтобы избежать запросов пароля, если у вас уже не установлен SSH без пароля для удаленного хоста.
Мне известно о Twisted conch
, но я бы предпочел избегать реализации scp самостоятельно через низкоуровневые ssh-модули.
Мне известно о paramiko
, модуле Python, который поддерживает SSH и SFTP; но он не поддерживает SCP.
Справочная информация: я подключаюсь к маршрутизатору, который не поддерживает SFTP, но поддерживает SSH/SCP, поэтому SFTP не подходит.
EDIT:
Это дубликат Как скопировать файл на удаленный сервер в Python, используя SCP или SSH?. Однако, этот вопрос не дает конкретного ответа scp, который имеет дело с ключами из Python. Я надеюсь на способ запуска кода вроде
import scp
client = scp.Client(host=host, user=user, keyfile=keyfile)
# or
client = scp.Client(host=host, user=user)
client.use_system_keys()
# or
client = scp.Client(host=host, user=user, password=password)
# and then
client.transfer('/etc/local/filename', '/etc/remote/filename')
Ответы
Ответ 1
Попробуйте модуль Python scp для Paramiko. Это очень просто в использовании. Смотрите следующий пример:
import paramiko
from scp import SCPClient
def createSSHClient(server, port, user, password):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, user, password)
return client
ssh = createSSHClient(server, port, user, password)
scp = SCPClient(ssh.get_transport())
Затем позвоните scp.get()
или scp.put()
, чтобы выполнить операции SCP.
(код SCPClient)
Ответ 2
Возможно, вам будет интересно попробовать Pexpect (исходный код). Это позволит вам иметь дело с интерактивными подсказками для вашего пароля.
Вот фрагмент примера использования (для ftp) с основного сайта:
# This connects to the openbsd ftp site and
# downloads the recursive directory listing.
import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('[email protected]')
child.expect ('ftp> ')
child.sendline ('cd pub')
child.expect('ftp> ')
child.sendline ('get ls-lR.gz')
child.expect('ftp> ')
child.sendline ('bye')
Ответ 3
Вы также можете проверить paramiko. Там нет модуля scp (пока), но он полностью поддерживает sftp.
[EDIT]
Извините, пропустил линию, где вы упомянули paramiko.
Следующий модуль - это просто реализация протокола scp для paramiko.
Если вы не хотите использовать paramiko или conch (единственные реализации ssh, которые я знаю для python), вы можете переработать это, чтобы выполнить регулярный сеанс ssh с использованием труб.
scp.py для paramiko
Ответ 4
если вы устанавливаете putty на win32, вы получаете pscp (scty).
чтобы вы могли также использовать взломы os.system на win32.
(и вы можете использовать агент-шпатель для управления ключами)
извините, это всего лишь взломать
(но вы можете обернуть его в класс python)
Ответ 5
Не удалось найти прямой ответ, и этот модуль "scp.Client" не существует. Вместо этого меня это устраивает:
from paramiko import SSHClient
from scp import SCPClient
ssh = SSHClient()
ssh.load_system_host_keys()
ssh.connect('example.com')
with SCPClient(ssh.get_transport()) as scp:
scp.put('test.txt', 'test2.txt')
scp.get('test2.txt')
Ответ 6
Посмотрите на fabric.transfer.
from fabric import Connection
with Connection(host="hostname",
user="admin",
connect_kwargs={"key_filename": "/home/myuser/.ssh/private.key"}
) as c:
c.get('/foo/bar/file.txt', '/tmp/')
Ответ 7
Прошло довольно много времени с тех пор, как был задан этот вопрос, и тем временем появилась другая библиотека, которая может справиться с этим: Вы можете использовать функцию копирования, включенную в библиотеку Plumbum:
import plumbum
r = plumbum.machines.SshMachine("example.net")
# this will use your ssh config as 'ssh' from shell
# depending on your config, you might also need additional
# params, eg: 'user="username", keyfile=".ssh/some_key"'
fro = plumbum.local.path("some_file")
to = r.path("/path/to/destination/")
plumbum.path.utils.copy(fro, to)
Ответ 8
Вы можете использовать подпроцесс пакета и командный вызов для использования команды scp из оболочки.
from subprocess import call
cmd = "scp [email protected]:files [email protected]:files"
call(cmd.split(" "))
Ответ 9
На сегодняшний день, лучшее решение, вероятно, AsyncSSH
https://asyncssh.readthedocs.io/en/latest/#scp-client
async with asyncssh.connect('host.tld') as conn:
await asyncssh.scp((conn, 'example.txt'), '.', recurse=True)
Ответ 10
Хммм, возможно, другим вариантом было бы использовать что-то вроде sshfs (там sshfs для Mac тоже). Как только ваш маршрутизатор установлен, вы можете просто скопировать файлы прямо. Я не уверен, что это работает для вашего конкретного приложения, но это приятное решение для удобства.
Ответ 11
Я еще недавно собрал копию SCP python script, которая зависит от paramiko. Он включает в себя код для обработки соединений с закрытым ключом или ключевым агентом SSH с откатом для аутентификации паролей.
http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/
Ответ 12
Если вы находитесь на * nix, вы можете использовать sshpass
sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path
Ответ 13
Я не думаю, что есть какой-либо один модуль, который вы можете легко загрузить для реализации scp, однако вы можете найти это полезным: http://www.ibm.com/developerworks/linux/library/l-twist4.html