[英]Output garbled when launching multiple ssh-sessions with pseudo-tty (need remote process to exit when ssh disconnects/is killed)
我有一個 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
22
33
44
11
22
33
44
輸出不同。 有時它有效,但大多數時候我會得到那些奇怪的縮進。 實際上,我想啟動遠程 python 進程(locust load gen slave),但我已將其簡化為僅使用 echo。
我嘗試過的事情:
11^M$
22^M$
33^M$
44^M$
11$
22$
33$
44$
11$
22$
33$
44$
我不確定是 python 問題還是 SSH 問題。 我的猜測是我需要使用某種行緩沖,但我不知道如何:-/
我在 MacOS Mojave 上,如果重要的話,我已經在 iTerm2 和 Term 中嘗試過。
編輯:我不確定它是否相關,但是如果我確保 python 繼續運行直到 ssh 會話終止(通過在腳本末尾添加 time.sleep(10) ),問題似乎會更頻繁地發生
編輯 2:我嘗試了 @FLemaitre 的解決方案(不使用 -tt 並明確殺死),它在簡單的情況下有效,但在產卵蝗蟲時無效:
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 -c locust --slave ...
進程啟動。 它在 ssh 被殺死時死亡,但 locust 本身(上述過程的子進程)不會:-/
我使用以下腳本系統地重現了該問題:
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 似乎相互沖突。 最終,用於運行此腳本的終端也被破壞了(而它不是來源):
>cat test2.py
import subprocess
import time
import atexit
... etc ...
我檢查了文檔,這個 -t 選項似乎比你實際想要實現的要多得多。 當我刪除第二個 t 和 -q 選項時,我有時(不經常)收到一條神秘的錯誤消息,指出出現問題(但我不再設法重現它)。 我用谷歌檢查過,但沒有太大成功。 不過,我相信這個選項是矯枉過正的,我寧願專注於不朽的過程。 這個問題是眾所周知的:
使用 bash 通過 ssh 啟動進程,然后在 sigint 上終止它
第二個答案是您的 -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 方面的問題)。 它似乎適用於“kill -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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.