在老家 2 天,花了点时间,折腾了下 python 代码,之前一直遇到个偶现点问题,这两天总算解决了。
问题的核心是,你知道怎么正确用 python 代码调用 linux 上的 shell 命令。
这里回涉及 2 个问题。
1、如何执行本机上的 linux 命令?
2、如何执行远程机器上的 linux 命令?
可以执行本机 shell 命令的相关 python 模块和函数有好几个,不过有一些已经被废弃或移除。
subprocess 模块用于创建子进程, 这个模块用于替换旧版本中的一些模块, 如:os.system,
os.spawn*, os.popen*, os.popen*, popen2., commands., subprocess 允许你能创建很多子进程, 创建的时候能能指定子进程和子进程的输入、输出、错误输出管道, 执行后能获取输出结果和执行状态。
在 python3.5 之后的版本中, 官方文档中提倡通过 subprocess.run() 函数替代其他函数来使用 subprocess 模块的功能。
测试:自己写了个简单的 demo,验证了 subprocess 调用 run 函数执行 linux 命令的时候是阻塞的,一直会等到命令执行完,再往下走。
另外,可以根据结果的 returncode 码,进行判断,linux 命令有没有执行成功。
关于 python 远程执行 Linux,用的最多的还是 paramiko 模块,我之前也是用了这个模块,但是踩坑了。
核心主要代码
sshclient = paramiko.SSHClient()
sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshclient.connect(ip, int(port), user, pwd, timeout=60)
check_in, check_out, check_err = sshclient.exec_command(self.check_slave_cmd)
坑就是,exec_command 函数是非阻塞的,不管命令有没有执行成功,python 代码就往下走了。所以,有时候回出现偶像的 bug,因为取决于命令执行的快慢和网速,譬如,假设你执行的 shell 命令耗时比较久,而代码已经执行到下面,发现没有你 shell 命令的结果就报错了。
检测一下该 shell 命令的执行状态。调用 recv_exit_status(),该函数回一直阻塞中,直到 shell 命令结束,一般正常接受的 status 是 0.。
所以,当你要用到这个 paramiko 模块执行远程机器的 shell 命令的话,要多个心眼,保证 shell 命令有没有执行完成,会不会影响你的代码。
更多内容可以学习《测试工程师 Python 工具开发实战》书籍