tldr
有没有办法检查Paramiko中的shell是否已完成执行命令?
长
我们正在尝试在AWS上自动执行一些相当普通的服务器任务。我们在Paramiko和boto3方面取得了很好的进展,但是在构建我们的基础AMI的过程中遇到了一些障碍。
以下内容为我们提供了一个可以使用的交互式shell:
def create_ssh_channel(instance, keypair):
# we need to convert the string into a file-like object
rsa_key = paramiko.RSAKey.from_private_key(io.StringIO(keypair.key_material.decode()))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=instance.public_dns_name, username='ubuntu', pkey=rsa_key, )
channel = ssh.invoke_shell()
return channel
然后我们可以发出有用的命令:
channel.send('sudo apt-get update')
channel.send('\n')
从流中读取:
stream_data = str()
while True:
if channel.recv_ready():
stream_data += channel.recv(9999)
else:
break
这让我们可以相当可靠地完成大部分工作,包括获取外部资源,将日志输出到其他服务等。我们遇到困难的时候是我们需要运行顺序命令,这依赖于第一个命令完成。例如,我们需要sudo apt-get install python-pip
,然后是pip install lxml
。
问题在于,虽然大多数命令都会给shell提供相当规律的更新,但并非所有命令都可以。我们已经尝试了几种方法来解决这个问题,包括使用以下if stream_data.endswith(':~$ ')
来打破循环,但这最多只是一次又一次。
是否有可靠的方法来检查最后执行的命令是否已在Paramiko shell中完成?