我有一個subprocess.Popen用于啟動目標程序的 python 腳本:一個網絡服務器。我想與目標進行交互,所以我將stdin,stdout和分配stderr給管道,現在我可以讀寫它們了。現在,網絡服務器鏈接 OpenSSL 庫以進行 TLS 處理。作為 TLS 處理的一部分,它會打開證書并提示輸入密碼。通常,在輸入密碼并按下回車鍵后,網絡服務器就會開始服務?,F在,您可能已經猜到了,我想從 python 腳本中輸入此密碼。通常,我需要做的是寫入服務器的stdin. 但是,有一個問題。當 OpenSSL 提示并讀取密碼時,它不使用stdin/ stdout。它打開/dev/tty并使用它。結果,我必須輸入密碼并手動輸入。下圖演示了這種情況。lsof下面,您可以看到服務器輸出的片段:memcached 25279 USER 0r FIFO 0,13 0t0 7771739 pipememcached 25279 USER 1w FIFO 0,13 0t0 7771740 pipememcached 25279 USER 2w FIFO 0,13 0t0 7771740 pipememcached 25279 USER 3r REG 8,1 3414 3414276 ....key.pemmemcached 25279 USER 4r CHR 5,0 0t0 13 /dev/ttymemcached 25279 USER 5w CHR 5,0 0t0 13 /dev/tty有沒有辦法攔截對/dev/tty服務器的調用,以便我可以直接從腳本寫入它?
1 回答

當年話下
TA貢獻1890條經驗 獲得超9個贊
通過使用 pty - 偽終端來實現您所描述的內容的標準方法。pty 看起來與普通 tty 完全一樣,只是它是由軟件而不是實際終端或終端仿真器控制的。
在您的情況下,您可以輕松地使用pty
python 標準庫中的模塊,它提供了一些使用 pty 的實用程序。具體看pty.spawn()函數:
生成一個進程,并將其控制終端連接到當前進程的標準 io. 這通常用于阻止堅持從控制終端讀取的程序。預計在 pty 后面生成的進程最終將終止,并且當它確實生成時將返回。
用法示例:
import subprocess, sys
openssl_cmd = ['openssl', 'foo', 'bar']
p = subprocess.Popen([sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])', *openssl_cmd])
p.stdin.write('password\n')
print(p.wait())
在這個例子中,我們沒有直接運行 openssl,而是使用 運行它spawn
,這意味著無論我們寫入進程的標準輸入,openssl 都會從它的/dev/tty
.
添加回答
舉報
0/150
提交
取消