NO.9:自学python之路------SSHClient、进程、线程
摘要
毕业啊,找工作啊不知不觉都两年没有更新了,最近经常查东西还需要翻开博客看之前的内容,觉得还是有必要继续写下去。就开始今天的内容吧。
正文
SSH客户端
在windows上经常有需要远程连接linux去做一些事情,一般情况都会使用Xmanager这款软件。如果刚好没有这个软件急需使用python与linux交互可以吗?答案是肯定的,不过需要首先安装paramiko这个包。在环境中使用pip安装python的包的方法如下:
pip install paramiko
安装好包以后和linux的交互代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.xxx.xxx', port=22, username='linux用户名', password='linux用户密码') # 执行命令 stdin, stdout, stderr = ssh.exec_command('ls') # 返回值分别为:标准输入 输出 错误 # 获取命令结果 result = stdout.read() print(result.decode()) result = stderr.read() print(result.decode()) # 关闭连接 ssh.close()
可以发现这样写代码时,别人可以轻易的从代码中找到linux机器的用户名和密码。这样对安全没有保障,这时候就需要使用ssh密钥RSA非对称密钥验证了。密钥生成方法,首先在linux的terminal中输入如下指令:
ssh-keygen -t rsa
多回车几次就生成了密钥,然后将公钥id_rsa.pub传输给连接方使用,私钥id_rsa留给被连接方使用。得到公钥后就可以免除密码登录远程主机了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import paramiko # 输入密钥位置 private_key = paramiko.RSAKey.from_private_key_file('id_rsa') # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.3.4', port=22, username='kyle', pkey=private_key) # 执行命令 stdin, stdout, stderr = ssh.exec_command('df') # 标准输入 输出 错误 # 获取命令结果 result = stdout.read() print(result.decode()) result = stderr.read() print(result.decode()) # 关闭连接 ssh.close()
同样paramiko还可以实现sftp功能传输文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa') transport = paramiko.Transport(('192.168.3.4', 22)) # transport.connect(username='用户名', password='密码') transport.connect(username='用户名', pkey=private_key) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put('id_rsa.pub', '/tmp/test.py') # sftp.get('/tmp/test.py', 'id_rsa.pub') transport.close()
进程与线程
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程之间共享内存空间,进程之间的内存独立,同一进程的线程之间可以直接通信,两个进程之间需要一个代理来通信。由于python解释器的原因,同时只有一个线程在运行。
python线程事件实现如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time import threading event = threading.Event() def light(): count = 0 event.set() while True: if 30 > count > 20: event.clear() # 清空标志位 print('\033[41;1m红灯停\033[0m') elif count > 30: event.set() # 设置标志位 count = 0 else: print("\033[42;1m绿灯行\033[0m") time.sleep(1) count += 1 def car(name): while True: if event.is_set(): # 标志位被设置 print('%s 开始行驶' % name) time.sleep(1) else: print('%s 正在等待' % name) event.wait() print('绿灯亮了开始行驶') if __name__ == "__main__": t = threading.Thread(target=light, ) t.start() t1 = threading.Thread(target=car, args=('小汽车', )) t1.start()
python线程锁实现如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import time import threading def run(info): semaphore.acquire() # 加锁 只有python2需要 global num num += 1 print(info, '正在执行') time.sleep(5) semaphore.release() # 释放锁 num = 0 semaphore = threading.BoundedSemaphore(5) if __name__ == "__main__": t_list = [] for i in range(100): t = threading.Thread(target=run, args=('任务%d' % i,)) # t.setDaemon(True) # 把当前线程设置为守护线程 t.start() t_list.append(t) for t in t_list: t.join() print('所有进程结束: ', num) # 查看线程名称
python队列的实现如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import queue # q = queue.Queue(maxsize=3) # 先进先出 最大进入3个过多会卡住 # q = queue.LifoQueue() # 后入先出 q = queue.PriorityQueue() # 存储时可以设置优先级 q.put((10, '队列1')) q.put((20, '队列2')) q.put((-10, '队列3')) q.put((0, '队列4')) q.put((5, '队列5')) # q.put('队列2') print(q.qsize()) print(q.get()) print(q.get()) print(q.empty()) # 队列是否为空 # print(q.get()) # 程序卡住等待新的队列加入 print(q.get(timeout=1)) # 程序等待时间 print(q.get_nowait()) # 不等待 相当于 q.get(block=False)