Using the pexpect module

More info about pexpect is at [http://www.noah.org/wiki/pexpect].

#!/usr/bin/env python2.5
 
"""
Usage: %prog [options] file1 [file2] [extra_files] destination
 
Downloads a file (or files) via SFTP.
 
Example: sftp_download.py --host=sftp.example.com --path=/path/to/file/
         --username=monetate --password=PaSsWoRd download_me.xml
         download_me_too.xml /destination/
 
"""
 
from optparse import OptionParser
import os
import sys
 
import pexpect
 
######################### parameters & settings ########################
 
parser = OptionParser(usage=__doc__.strip())
 
parser.add_option('--host', dest='host', action='store', type='string',
                  help='SFTP host')
parser.add_option('--path', dest='path', action='store', type='string',
                  help='SFTP path')
parser.add_option('--username', dest='username', action='store', type='string',
                  help='SFTP login username')
parser.add_option('--password', dest='password', action='store', type='string',
                  help='SFTP login password')
 
############################### functions ##############################
 
def download_files(files, destination, host, path, username, password):
    """
    Log in to the SFTP server using the username and password
    provided and download the specified files.
    """
    sftp_opts = ['-o', 'PasswordAuthentication=yes',
                 '%s@%s' % (username, host)]
    p = pexpect.spawn('sftp', sftp_opts)
    p.logfile = sys.stdout
 
    try:
        p.expect('(?i)password:')
        x = p.sendline(password)
        x = p.expect(['Permission denied','sftp>'])
        if x == 0:
            print 'Permission denied for password:'
            print password
            p.kill(0)
        else:
            x = p.sendline('cd ' + path)
            for file in files:
                x = p.expect('sftp>')
                x = p.sendline('get ' + file + ' ' + destination)
            x = p.expect('sftp>')
            x = p.isalive()
            x = p.close()
            retval = p.exitstatus
    except pexpect.EOF:
        print str(p)
        return 'SFTP file transfer failed due to premature end of file.'
    except pexpect.TIMEOUT:
        print str(p)
        return 'SFTP file transfer failed due to timeout.'
 
############################## main block ##############################
 
if __name__ == '__main__':
    options, args = parser.parse_args()
    if not args:
        parser.print_help()
        sys.exit(1)
    destination = args[-1]
    files = args[:-1]
 
    status = download_files(files, destination, options.host, options.path,
                            options.username, options.password)
 
    sys.exit(status)

执行上述脚本时可能会报错:
Traceback (most recent call last):
  File "./sshlinux.sh", line 10, in <module>
    s.login (hostname, username, password) 
  File "/usr/local/python-2.7/lib/python2.7/site-packages/pxssh.py", line 243, in login
    if not self.synch_original_prompt():
  File "/usr/local/python-2.7/lib/python2.7/site-packages/pxssh.py", line 134, in synch_original_prompt
    self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt
  File "/usr/local/python-2.7/lib/python2.7/site-packages/pexpect.py", line 824, in read_nonblocking
    raise TIMEOUT ('Timeout exceeded in read_nonblocking().')
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().

这个问题可以调整错误信息中的路径进行修改/usr/lib/python-2.7/lib/python2.7/site-packages/pxssh.py文件,在pxssh.py文件中:
在def synch_original_prompt (self):方法下第一个self.read_nonblocking(size=10000,timeout=1) 前面增加两行代码

self.sendline()  
time.sleep(0.5)


Using the paramiko module

More info about paramiko is at [http://www.lag.net/paramiko/].

#!/usr/bin/env python2.5

"""
Usage: %prog [options] file1 [file2] [extra_files] destination

Downloads a file (or files) via SFTP.

Example: sftp_download.py --host=sftp.example.com --path=/path/to/file/
         --username=monetate --password=PaSsWoRd download_me.xml
         download_me_too.xml /destination/
"""

from optparse import OptionParser
import os
import sys

import paramiko

######################### parameters &amp; settings ########################

parser = OptionParser(usage=__doc__.strip())

parser.add_option('--host', dest='host', action='store', type='string',
                  help='SFTP host')
parser.add_option('--path', dest='path', action='store', type='string',
                  help='SFTP path')
parser.add_option('--username', dest='username', action='store', type='string',
                  help='SFTP login username')
parser.add_option('--password', dest='password', action='store', type='string',
                  help='SFTP login password')

############################### functions ##############################

def download_files(files, destination, host, path, username, password):
    """
    Log in to the SFTP server using the username and password
    provided and download the specified files.
    """

    transport=paramiko.Transport(host)
    transport.connect(username=username, password=password)
    sftp=paramiko.SFTPClient.from_transport(transport)
    for file in files:
        sftp.get(path + file, destination + file)

############################## main block ##############################

if __name__ == '__main__':
    options, args = parser.parse_args()
    if not args:
        parser.print_help()
        sys.exit(1)
    destination = args[-1]
    files = args[:-1]

    status = download_files(files, destination, options.host, options.path,
                            options.username, options.password)

    sys.exit(status)