# 读取服务器日志,并打印
if __name__ == '__main__':
# with SSHTunnelForwarder(
# ('120.25.*.*', 22), #跳板机IP,端口
# ssh_username="root", #跳板机用户名
# ssh_password="i8khGtwa7sQra5hXXXXX", #跳板机密码
# # ssh_pkey="./rsa", #ssh 连接使用密钥证书登录,该参数必须;该路径为目标服务器的公钥证书
# # ssh_private_key_password="i8khGtwa7sXXXX", #如果公钥证书有密码,该参数必须,如果没有密码,该参数注释掉
# remote_bind_address=('10.20.XXX', 22), #远程服务器地址、端口
# local_bind_address=('127.0.0.1', 10022) #本机固定127
# ) as tunnel: #以上跳板机代码注销后,下面是直接访问服务器代码
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('10.206.28.139', 22, username='haitian', password='Sf123456!@#', timeout=30)
# do some operations with client session
remote_command = "tail -fn 50 /app/deploy/nwms-base/logs/error.log "
stdin, stdout, stderr = client.exec_command(remote_command)
last_line = stdout.read() # 此处程序会死锁
a = last_line.decode('utf - 8')
print(a)
client.close()
死锁:(引用 https://blog.csdn.net/weixin_39629617/article/details/110773119)
如果设置了stdout或stderr,subprocess就会调用os.pipe创建一个管道用于其和子进程之间的通信,而上面的问题正好是cmd输出的数据把pipe塞满,无法继续往pipe里写入数据导致程序hang住,而我们没有去读出pipe数据,而是死等子进程完成,导致死锁。
具体大小的话windows只有4kb,而linux有64kb(辣鸡windows)
那么如何解决呢
解决办法一:
使用communicate及时读出pipe中内容,避免堵死,但在输出量非常大的情况下会影响性能:
这也是官方文档里推荐的做法,但是不能乱用,因为会影响性能.
解决办法二:
使用文件代替PIPE,但是这样子的话传给客户端的就只能是文件了。
fdout = open(len(procs)+”.out”, ‘w’)
fderr = open(len(procs)+”.err”, ‘w’)
总结:
两种方法需要自己根据情况进行取舍,都有各自的优势和劣势。
原创文章,作者:745907710,如若转载,请注明出处:https://blog.ytso.com/272258.html