使用paramiko的SFTP get或put整个目录

  在《使用paramiko执行远程linux主机命令》中举例说明了执行远程linux主机命令的方法,其实paramiko还支持SFTP传输文件。

  由于get或put方法每次只能传输一个文件,而不是整个目录,因此我们先看一下传输单个文件的方法,其实非常简单,网上也有很多参考资料了。

  还是直接使用前文中定义的类,我们添加两个方法即可(本文中不需要使用的方法先用pass代替了):

 1 # 定义一个类,表示一台远端linux主机
 2 class Linux(object):
 3     # 通过IP, 用户名,密码,超时时间初始化一个远程Linux主机
 4     def __init__(self, ip, username, password, timeout=30):
 5         self.ip = ip
 6         self.username = username
 7         self.password = password
 8         self.timeout = timeout
 9         # transport和chanel
10         self.t = ‘‘
11         self.chan = ‘‘
12         # 链接失败的重试次数
13         self.try_times = 3
14
15     # 调用该方法连接远程主机
16     def connect(self):
17          pass
18
19     # 断开连接
20     def close(self):
21         pass
22
23     # 发送要执行的命令
24     def send(self, cmd):
25         pass
26
27     # get单个文件
28     def sftp_get(self, remotefile, localfile):
29         t = paramiko.Transport(sock=(self.ip, 22))
30         t.connect(username=self.username, password=self.password)
31         sftp = paramiko.SFTPClient.from_transport(t)
32         sftp.get(remotefile, localfile)
33         t.close()
34
35     # put单个文件
36     def sftp_put(self, localfile, remotefile):
37         t = paramiko.Transport(sock=(self.ip, 22))
38         t.connect(username=self.username, password=self.password)
39         sftp = paramiko.SFTPClient.from_transport(t)
40         sftp.put(localfile, remotefile)
41         t.close()

  注意上面的remotefile, localfile一定是文件,不能是目录,对于sftp_get,localfile指定本地将要保存的文件名,可以与remotefile的名字不一样;

  而sftp_put中,remotefile指定远端将要保存的文件名,可与localfile的名字不一样,测试代码如下:

 1 if __name__ == ‘__main__‘:
 2     remotefile = r‘/home/sea/test/xxoo.txt‘
 3     localfile = r‘E:\PythonFiles\Learn\ooxx.txt‘
 4
 5     host = Linux(‘192.168.180.128‘, ‘root‘, ‘1234‘)
 6
 7     # 将远端的xxoo.txt get到本地,并保存为ooxx.txt
 8     host.sftp_get(remotefile, localfile)
 9
10     # # 将本地的xxoo.txt put到远端,并保持为xxoo.txt
11     # host.sftp_put(localfile, remotefile)

  

  下面再来考虑下如何传输整个目录?

  有两种思路:

  1 如果是要get则采用已经定义的connect方法连接到linux主机,然后通过send方法执行tar命令将需要传输的整个目录打包,再传输打包后的文件即可,如果是put则需在本地打包

该方法的缺点是:在远端或者本地进行打包或者解压,并且打包会占用临时存储空间,如果是远端打包还需先SSH链接linux主机。

优点是:不用做目录扫描处理。

2 遍历需要get或put的目录及其子目录,然后依次传输每一个文件。优点是不需要SSH登陆和打包解压,缺点是需要做目录扫描,但是目录扫描是很简单的,因此我们采用这种方法。

  先来看看Get,由于要扫描目录,因此先定义一个方法用来对指定目录进行扫描,找出该目录及所有子目录中的所有文件。

  那么问题来了,怎么扫描目录呢?使用python的os库的方法吗?肯定是不行的,因为python的os库的方法都是对本地目录或文件的操作,它是无法操作远程linux主机上的文件和目录的。

  其实paramiko的SFTP接口提供了操作远端linux主机上的文件和目录的方法,只要建立了与远端的SFTP连接后,就可以执行文件和目录操作。

  下面是获取远端linux主机上指定目录及其子目录下的所有文件的方法,也是定义在上面的类中的。

 1 # ------获取远端linux主机上指定目录及其子目录下的所有文件------
 2     def __get_all_files_in_remote_dir(self, sftp, remote_dir):
 3         # 保存所有文件的列表
 4         all_files = list()
 5
 6         # 去掉路径字符串最后的字符‘/‘,如果有的话
 7         if remote_dir[-1] == ‘/‘:
 8             remote_dir = remote_dir[0:-1]
 9
10         # 获取当前指定目录下的所有目录及文件,包含属性值
11         files = sftp.listdir_attr(remote_dir)
12         for x in files:
13             # remote_dir目录中每一个文件或目录的完整路径
14             filename = remote_dir + ‘/‘ + x.filename
15             # 如果是目录,则递归处理该目录,这里用到了stat库中的S_ISDIR方法,与linux中的宏的名字完全一致
16             if S_ISDIR(x.st_mode):
17                 all_files.extend(self.__get_all_files_in_remote_dir(sftp, filename))
18             else:
19                 all_files.append(filename)
20         return all_files

  在上面的方法中,参数sftp表示已经建立的sftp连接,remote_dir是要扫描的远端目录。

  在扫描目录的时候,使用的listdir_attr方法会列出指定目录下的所有文件或目录,并且还会列出其属性,比如st_size,st_uid,st_gid,st_mode,st_atime,st_mtime,

  这些属性与linux中的stat函数返回的属性类似,我们就是根据其中的st_mode属性来判断是一个目录还是文件,并且处理st_mode的方法(位于stat模块中)也是与linux中定义的宏一致的。

  获取到指定目录下的所有文件之后,传输就比较简单了,依次遍历get即可:

 1     def sftp_get_dir(self, remote_dir, local_dir):
 2         t = paramiko.Transport(sock=(self.ip, 22))
 3         t.connect(username=self.username, password=self.password)
 4         sftp = paramiko.SFTPClient.from_transport(t)
 5
 6         # 获取远端linux主机上指定目录及其子目录下的所有文件
 7         all_files = self.__get_all_files_in_remote_dir(sftp, remote_dir)
 8         # 依次get每一个文件
 9         for x in all_files:
10             filename = x.split(‘/‘)[-1]
11             local_filename = os.path.join(local_dir, filename)
12             print u‘Get文件%s传输中...‘ % filename
13             sftp.get(x, local_filename)

  上面方法将remote_dir目录中的所有文件都get到了本地local_dir目录中,但是在本地没有保持与远端一致的目录结构,只是简单将所有文件保存在local_dir目录中。

  如果要保持与远端的目录结构一致,就需要在本地ocal_dir中创建子目录,这里暂且不讲述了,如有这种需求可思考一下。

  下面再来看看put,其实与get几乎一样,现在扫描本地目录,然后依次遍历文件并put到远端,

  由于是对本地目录做扫描,因此不需要调用SFTP中的文件目录处理接口了,直接使用python的os库即可,代码如下:

  

 1  # ------获取本地指定目录及其子目录下的所有文件------
 2     def __get_all_files_in_local_dir(self, local_dir):
 3         # 保存所有文件的列表
 4         all_files = list()
 5
 6         # 获取当前指定目录下的所有目录及文件,包含属性值
 7         files = os.listdir(local_dir)
 8         for x in files:
 9             # local_dir目录中每一个文件或目录的完整路径
10             filename = os.path.join(local_dir, x)
11             # 如果是目录,则递归处理该目录
12             if os.path.isdir(x):
13                 all_files.extend(self.__get_all_files_in_local_dir(filename))
14             else:
15                 all_files.append(filename)
16         return all_files
17
18     def sftp_put_dir(self, local_dir, remote_dir):
19         t = paramiko.Transport(sock=(self.ip, 22))
20         t.connect(username=self.username, password=self.password)
21         sftp = paramiko.SFTPClient.from_transport(t)
22
23         # 去掉路径字符穿最后的字符‘/‘,如果有的话
24         if remote_dir[-1] == ‘/‘:
25             remote_dir = remote_dir[0:-1]
26
27         # 获取本地指定目录及其子目录下的所有文件
28         all_files = self.__get_all_files_in_local_dir(local_dir)
29         # 依次put每一个文件
30         for x in all_files:
31             filename = os.path.split(x)[-1]
32             remote_filename = remote_dir + ‘/‘ + filename
33             print u‘Put文件%s传输中...‘ % filename
34             sftp.put(x, remote_filename)

  测试代码如下:

 1 if __name__ == ‘__main__‘:
 2     remote_path = r‘/home/sea‘
 3     local_path = r‘E:\PythonFiles\Learn\testsftp‘
 4
 5     host = Linux(‘192.168.180.128‘, ‘root‘, ‘1234‘)
 6
 7     # 将远端remote_path目录中的所有文件get到本地local_path目录
 8     host.sftp_get_dir(remote_path, local_path)
 9     # # 将本地local_path目录中的所有文件put到远端remote_path目录
10     # host.sftp_put_dir(remote_path, local_path)
11
12 # 运行结果
13 Get文件.profile传输中...
14 Get文件.inputrc传输中...
15 Get文件.emacs传输中...
16 Get文件.bash_history传输中...
17 Get文件.bashrc传输中...

  

时间: 2024-08-05 23:40:32

使用paramiko的SFTP get或put整个目录的相关文章

centos下配置sftp且限制用户访问目录

第一步:创建sftp服务用户组,创建sftp服务根目录 groupadd sftp #此目录及上级目录的所有者(owner)必须为root,权限不高于755,此目录的组最好设定为sftp mkdir /srv/sftp chown -R root:sftp /srv/sftp chmod -R 0755 /srv/sftp 第二步:备份sshd配置文件然后编辑 mv /etc/ssh/sshd_config ~/backup/sshd_config_xxx vim /etc/ssh/sshd_c

Linux sftp限制用户访问指定目录

一.创建新用户: [root@controller ~]# useradd test[root@controller ~]# passwd testNew password: BAD PASSWORD: The password is a palindromeRetype new password: passwd: all authentication tokens updated successfully. 二.修改sshd配置文件: [root@controller ~]# vi /etc/

python paramiko模块sftp异常:paramiko.ssh_exception.SSHException: EOF during negotiation

python paramiko模块ftp报错: Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/lib/python2.7/dist-packages/paramiko/sftp_client.py", line 170, in from_transportreturn cls(chan)File "/usr/lib/py

centos下配置sftp且限制用户访问目录[转]

第一步:创建sftp服务用户组,创建sftp服务根目录 groupadd sftp #此目录及上级目录的所有者(owner)必须为root,权限不高于755,此目录的组最好设定为sftp mkdir /srv/sftp chown -R root:sftp /srv/sftp chmod -R 0755 /srv/sftp 第二步:备份sshd配置文件然后编辑 mv /etc/ssh/sshd_config ~/backup/sshd_config_xxx vim /etc/ssh/sshd_c

sftp 限制用户登陆指定目录(家目录)

本文源地址http://blog.chinaunix.net/uid-42741-id-3069880.html 即限制 sftp 用户登陆后,只能在家目录下活动,不能到其他或上级目录 该功能需要4.8以上版本 [[email protected] ~]# ssh -V OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb2013 以下操作都是在root下 [[email protected] ~]# cp/etc/ssh/sshd_config{,.old} [[

Linux创建用户,SFTP只允许访问指定目录

首先创建用户 useradd lus1passwd lus1 我这里配置lus1这个用户目录,为sftp指向目录,即/home/lus1/ vim /etc/ssh/sshd_config //这个记得要在原有的配置文件注释掉 #Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp Match User lus1 //lus1 是我们要配置的用户 ChrootDirectory /home/lus

python paramiko模块

paramiko模块是python中很重要的模块,他的功能呢主要分为两大块功能.一个是模拟SSH功能登录到远程主机上执行命令.一个是模拟SFTP功能传输文件. paramiko支持密码登陆方式和免密码的私钥登录方式. 密码登陆方式代码如下: #!/usr/bin/env python # coding:utf-8 import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 访问未知主机时候的策略,允许连接不在know_hosts文件中的主机 ss

第十八章 Python批量管理主机(paramiko、fabric与pexpect)

本章节主要讲解运维工程师比较感兴趣的知识,那就是运维批量管理,在Python下有paramiko.fabric和pexpect这三个模块可帮助运维实现自动化部署.批量执行命令.文件传输等常规任务,接下来一起看看它们的使用方法吧! 18.1 paramiko paramiko模块是基于Python实现的SSH远程安全连接,用于SSH远程执行命令.文件传输等功能. 默认Python没有,需要手动安装:pip install paramiko 如安装失败,可以尝试yum安装:yum install p

python linux交互模块(paramiko、fabric与pexpect)

转载自: http://blog.csdn.net/alibert/article/details/54375276 paramiko paramiko模块是基于Python实现的SSH远程安全连接,用于SSH远程执行命令.文件传输等功能. 默认python没有,需要手动安装:pip install paramiko 如安装失败,可以尝试yum安装:yum install python-paramiko 18.1.1 SSH密码认证远程执行命令 1 2 3 4 5 6 7 8 9 10 11 1