[英]Capture standard output for command passed to an embedded terminal
我試圖捕獲我正在使用subprocess.Popen
運行的命令的輸出,並輸出到嵌入在tkinter構建的應用程序中的xterm終端。 我希望命令的輸出轉到終端並被捕獲,以便我可以分析信息。
在另一種情況下,我只使用subprocess.Popen
運行命令,並且不將輸出傳遞給終端。 我可以通過包含stdout=subprocess.PIPE, stderr=subprocess.STDOUT
獲得輸出
proc_output = subprocess.Popen('ls', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(str(proc_output.stdout.read()))
我猜我的編碼方式我可以將輸出發送到終端或變量,但不是兩者。
對於我的代碼示例,一旦終端打開,我必須在終端中手動鍵入tty
,然后將輸出放在tty
輸入字段中。 之后,我可以從cmd_entry
運行命令並將輸出發送到終端。
此代碼是此處答案的略微修改版本。
from tkinter import *
import subprocess
root = Tk()
termf = Frame(root, height=360, width=625)
termf.pack(fill=BOTH, expand=YES)
wid = termf.winfo_id()
f=Frame(root)
Label(f,text="/dev/pts/").pack(side=LEFT)
tty_index = Entry(f, width=3)
tty_index.insert(0, "1")
tty_index.pack(side=LEFT)
Label(f,text="Command:").pack(side=LEFT)
cmd_entry = Entry(f)
cmd_entry.insert(0, "ls -l")
cmd_entry.pack(side=LEFT, fill=X, expand=1)
def send_entry_to_terminal(*args):
tty="/dev/pts/%s" % tty_index.get()
proc = subprocess.Popen(f'{cmd_entry.get()} <{tty} >{tty} 2> {tty}',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print(str(proc.stdout.read())
# cmd(f'{e.get()} <{tty} >{tty} 2> {tty}')
cmd_entry.bind("<Return>", send_entry_to_terminal)
b = Button(f,text="Send", command=send_entry_to_terminal)
b.pack(side=LEFT)
f.pack(fill=X, expand=1)
# cmd(f'xterm -into {wid} -geometry 100x27 -sb -e "tty; sh" &')
subprocess.Popen(f'xterm -into {wid} -geometry 100x27 -sb &', shell=True)
root.mainloop()
我想要做的是讓任何命令的輸出與子進程一起運行以打印到終端並保存在變量中以便以后處理。 但是現在我只能得到一個或另一個。
首先將shell重定向轉換為本機Popen
功能:
with open(tty,'r+b',0) as f:
proc=subprocess.Popen(cmd_entry.get(),shell=True,
stdin=f,stdout=f,stderr=f)
if proc.wait(): warn_user(…)
那么如何保留輸出的副本應該是相當明顯的:
with open(tty,'r+b',0) as f:
proc=subprocess.Popen(cmd_entry.get(),shell=True,
stdin=f,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
out=[]
for l in proc.stdout:
f.write(l)
out.append(l)
out=b"".join(out)
if proc.wait(): warn_user(…)
請注意,該進程將為其輸出設置管道而不是(偽)終端,這可能會改變其行為( 例如 , ls
打印在單個列中,而git
不使用尋呼機)。 如果要保留終端行為,則必須打開自己的偽終端並將寫入的中繼輸出(可能包含各種控制序列)發送到xterm
創建的輸出。
您可能還希望將該進程設置為( xterm
)終端的前台進程組,以便它可以接收鍵盤信號; 這涉及到tcsetpgrp
,有點復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.