[python] How to scp in Python?

What's the most pythonic way to scp a file in Python? The only route I'm aware of is

os.system('scp "%s" "%s:%s"' % (localfile, remotehost, remotefile) )

which is a hack, and which doesn't work outside Linux-like systems, and which needs help from the Pexpect module to avoid password prompts unless you already have passwordless SSH set up to the remote host.

I'm aware of Twisted's conch, but I'd prefer to avoid implementing scp myself via low-level ssh modules.

I'm aware of paramiko, a Python module that supports SSH and SFTP; but it doesn't support SCP.

Background: I'm connecting to a router which doesn't support SFTP but does support SSH/SCP, so SFTP isn't an option.

EDIT: This is a duplicate of How to copy a file to a remote server in Python using SCP or SSH?. However, that question doesn't give an scp-specific answer that deals with keys from within Python. I'm hoping for a way to run code kind of like

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')

This question is related to python ssh paramiko scp

The answer is


I while ago I put together a python SCP copy script that depends on paramiko. It includes code to handle connections with a private key or SSH key agent with a fallback to password authentication.

http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/


Hmmm, perhaps another option would be to use something like sshfs (there an sshfs for Mac too). Once your router is mounted you can just copy the files outright. I'm not sure if that works for your particular application but it's a nice solution to keep handy.


You could also check out paramiko. There's no scp module (yet), but it fully supports sftp.

[EDIT] Sorry, missed the line where you mentioned paramiko. The following module is simply an implementation of the scp protocol for paramiko. If you don't want to use paramiko or conch (the only ssh implementations I know of for python), you could rework this to run over a regular ssh session using pipes.

scp.py for paramiko


if you install putty on win32 you get an pscp (putty scp).

so you can use the os.system hack on win32 too.

(and you can use the putty-agent for key-managment)


sorry it is only a hack (but you can wrap it in a python class)


Try the Python scp module for Paramiko. It's very easy to use. See the following example:

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())

Then call scp.get() or scp.put() to do SCP operations.

(SCPClient code)


I don't think there's any one module that you can easily download to implement scp, however you might find this helpful: http://www.ibm.com/developerworks/linux/library/l-twist4.html


Hmmm, perhaps another option would be to use something like sshfs (there an sshfs for Mac too). Once your router is mounted you can just copy the files outright. I'm not sure if that works for your particular application but it's a nice solution to keep handy.


if you install putty on win32 you get an pscp (putty scp).

so you can use the os.system hack on win32 too.

(and you can use the putty-agent for key-managment)


sorry it is only a hack (but you can wrap it in a python class)


Have a look at 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/')

I while ago I put together a python SCP copy script that depends on paramiko. It includes code to handle connections with a private key or SSH key agent with a fallback to password authentication.

http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/


You might be interested in trying Pexpect (source code). This would allow you to deal with interactive prompts for your password.

Here's a snip of example usage (for ftp) from the main website:

# 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')

I don't think there's any one module that you can easily download to implement scp, however you might find this helpful: http://www.ibm.com/developerworks/linux/library/l-twist4.html


import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect('<IP Address>', username='<User Name>',password='' ,key_filename='<.PEM File path')

#Setup sftp connection and transmit this script 
print ("copying")

sftp = client.open_sftp() 
sftp.put(<Source>, <Destination>)


sftp.close()

You might be interested in trying Pexpect (source code). This would allow you to deal with interactive prompts for your password.

Here's a snip of example usage (for ftp) from the main website:

# 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')

As of today, the best solution is probably 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)

Hmmm, perhaps another option would be to use something like sshfs (there an sshfs for Mac too). Once your router is mounted you can just copy the files outright. I'm not sure if that works for your particular application but it's a nice solution to keep handy.


You might be interested in trying Pexpect (source code). This would allow you to deal with interactive prompts for your password.

Here's a snip of example usage (for ftp) from the main website:

# 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')

It has been quite a while since this question was asked, and in the meantime, another library that can handle this has cropped up: You can use the copy function included in the Plumbum library:

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)

You could also check out paramiko. There's no scp module (yet), but it fully supports sftp.

[EDIT] Sorry, missed the line where you mentioned paramiko. The following module is simply an implementation of the scp protocol for paramiko. If you don't want to use paramiko or conch (the only ssh implementations I know of for python), you could rework this to run over a regular ssh session using pipes.

scp.py for paramiko


Hmmm, perhaps another option would be to use something like sshfs (there an sshfs for Mac too). Once your router is mounted you can just copy the files outright. I'm not sure if that works for your particular application but it's a nice solution to keep handy.


You might be interested in trying Pexpect (source code). This would allow you to deal with interactive prompts for your password.

Here's a snip of example usage (for ftp) from the main website:

# 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')

If you are on *nix you can use sshpass

sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path

You can use the package subprocess and the command call to use the scp command from the shell.

from subprocess import call

cmd = "scp user1@host1:files user2@host2:files"
call(cmd.split(" "))

It has been quite a while since this question was asked, and in the meantime, another library that can handle this has cropped up: You can use the copy function included in the Plumbum library:

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)

If you are on *nix you can use sshpass

sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path

if you install putty on win32 you get an pscp (putty scp).

so you can use the os.system hack on win32 too.

(and you can use the putty-agent for key-managment)


sorry it is only a hack (but you can wrap it in a python class)


Couldn't find a straight answer, and this "scp.Client" module doesn't exist. Instead, this suits me:

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')

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect('<IP Address>', username='<User Name>',password='' ,key_filename='<.PEM File path')

#Setup sftp connection and transmit this script 
print ("copying")

sftp = client.open_sftp() 
sftp.put(<Source>, <Destination>)


sftp.close()

I don't think there's any one module that you can easily download to implement scp, however you might find this helpful: http://www.ibm.com/developerworks/linux/library/l-twist4.html


if you install putty on win32 you get an pscp (putty scp).

so you can use the os.system hack on win32 too.

(and you can use the putty-agent for key-managment)


sorry it is only a hack (but you can wrap it in a python class)


Try the Python scp module for Paramiko. It's very easy to use. See the following example:

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())

Then call scp.get() or scp.put() to do SCP operations.

(SCPClient code)


You could also check out paramiko. There's no scp module (yet), but it fully supports sftp.

[EDIT] Sorry, missed the line where you mentioned paramiko. The following module is simply an implementation of the scp protocol for paramiko. If you don't want to use paramiko or conch (the only ssh implementations I know of for python), you could rework this to run over a regular ssh session using pipes.

scp.py for paramiko


I don't think there's any one module that you can easily download to implement scp, however you might find this helpful: http://www.ibm.com/developerworks/linux/library/l-twist4.html


Couldn't find a straight answer, and this "scp.Client" module doesn't exist. Instead, this suits me:

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')

As of today, the best solution is probably 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)

You can use the package subprocess and the command call to use the scp command from the shell.

from subprocess import call

cmd = "scp user1@host1:files user2@host2:files"
call(cmd.split(" "))

Have a look at 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/')

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to ssh

Starting ssh-agent on Windows 10 fails: "unable to start ssh-agent service, error :1058" How to solve "sign_and_send_pubkey: signing failed: agent refused operation"? key_load_public: invalid format ssh connection refused on Raspberry Pi Getting permission denied (public key) on gitlab Verify host key with pysftp Can't connect to Postgresql on port 5432 Checkout Jenkins Pipeline Git SCM with credentials? How to open remote files in sublime text 3 how to setup ssh keys for jenkins to publish via ssh

Examples related to paramiko

python paramiko ssh How to ssh connect through python Paramiko with ppk public key Paramiko's SSHClient with SFTP Running interactive commands in Paramiko How to scp in Python?

Examples related to scp

Copying files from server to local computer using SSH How to copy a file from remote server to local machine? scp files from local to remote machine error: no such file or directory How to download a file from my server using SSH (using PuTTY on Windows) Using putty to scp from windows to Linux SCP Permission denied (publickey). on EC2 only when using -r flag on directories scp copy directory to another server with private key auth Run local python script on remote server Send password when using scp to copy files from one server to another How does `scp` differ from `rsync`?