Python 使用伪tty启动多个ssh会话时输出混乱(ssh断开连接/终止时需要远程进程退出)
我有一个python脚本,它可以向服务器打开多个并发的伪tty ssh会话。我的问题是输出有误:Python 使用伪tty启动多个ssh会话时输出混乱(ssh断开连接/终止时需要远程进程退出),python,ssh,Python,Ssh,我有一个python脚本,它可以向服务器打开多个并发的伪tty ssh会话。我的问题是输出有误: for i in range(0, 3): subprocess.Popen( "ssh -tt -q myserver 'echo 11; echo 22; echo 33; echo 44;'", shell=True ) 输出: 11 22 33 44 11
for i in range(0, 3):
subprocess.Popen(
"ssh -tt -q myserver 'echo 11; echo 22; echo 33; echo 44;'",
shell=True
)
输出:
11
22
33
44
11
22
33
44
11
22
33
44
产量各不相同。有时它是有效的,但大多数时候我都会看到那些奇怪的凹痕。实际上,我希望启动远程python进程(一个Hocust load gen从属进程),但我已经将其简化为只使用echo
我尝试过的事情:
- universal_newlines=True,bufsize=1(没有帮助)
- remove-tt(修复了输出,但是如果python/ssh终止,远程进程不会立即消失,这是不希望的副作用)
- 管道连接到cat-e以获取隐藏字符(用于调试):
proc = subprocess.Popen(
"ssh servername 'locust --slave --master-port 7777 --no-web -f locustfile.py & read; kill $!'",
shell=True,
stdin=subprocess.PIPE,
)
time.sleep(10)
proc.kill()
proc.wait()
在远程服务器上,启动一个
bash-chocust--slave…
进程。当ssh被杀死时,它就会死亡,但蝗虫本身(上述过程的子进程)不会:-/我用以下脚本系统地重现了这个问题:
import subprocess
import time
if __name__ == "__main__":
for i in range(0, 10):
proc = subprocess.Popen(
"ssh -tt -q localhost 'echo 11; echo 22; echo 33; '",
shell=True
)
time.sleep(4)
我认为这个问题与Python无关。这些带有伪TTY的多个ssh似乎相互冲突。最终,用于运行此脚本的终端也出现了故障(但它没有来源):
我查看了文档,这个-t选项似乎比您实际想要实现的要多得多。当我删除第二个t和-q选项时,我有时(不经常)会收到一条神秘的错误消息,说明出现了问题(但我不再设法重现它)。我和谷歌联系过,但没有多大成功。尽管如此,我相信这个选择是过分的,我更愿意关注永恒的过程。这一问题众所周知:
第二个答案是您的-tt选项,但最好的答案非常适合您的示例,并且更优越(使用-tt可以解决终止的ssh传播,但不能解决Python及其子进程之间的相同问题)。例如:
import subprocess
import time
if __name__ == "__main__":
for i in range(0, 10):
proc = subprocess.Popen(
"ssh localhost 'sleep 90 & read ; kill $!'",
shell=True,
stdin=subprocess.PIPE
)
time.sleep(40)
使用此解决方案,stdin由所有参与者(python、python子流程、ssh流程、sleep流程)共享,链中任何一点的关闭都会被最终的业务流程检测到,从而触发正常的关闭
用蝗虫编辑:
我快速尝试了一下,问题是奴隶忽略了一个简单的“杀死”(看起来像是lucust方面的问题)。它似乎与“杀戮-9”一起工作:
import subprocess
import time
if __name__ == "__main__":
for i in range(0, 2):
proc = subprocess.Popen(
"ssh localhost 'python -m locust --slave --no-web -f ~devsup/users/flemaitre/tmp/locust_config.py & read ; kill -9 $!'",
shell=True,
stdin=subprocess.PIPE
)
time.sleep(40)
你好谢谢你的建议-我想我已经接近解决这个问题了,但我仍然有问题。更新了我的问题,以反映我用一个使用蝗虫的示例编辑了我的答案(从他们的文档中提取了一个虚拟配置)。谢谢!我将尝试更新一点问题,以更好地符合答案!
import subprocess
import time
if __name__ == "__main__":
for i in range(0, 10):
proc = subprocess.Popen(
"ssh localhost 'sleep 90 & read ; kill $!'",
shell=True,
stdin=subprocess.PIPE
)
time.sleep(40)
import subprocess
import time
if __name__ == "__main__":
for i in range(0, 2):
proc = subprocess.Popen(
"ssh localhost 'python -m locust --slave --no-web -f ~devsup/users/flemaitre/tmp/locust_config.py & read ; kill -9 $!'",
shell=True,
stdin=subprocess.PIPE
)
time.sleep(40)