[英]Send STDIN and get STDOUT from a running process
我有一個可以運行的 c++ 編譯代碼,我們稱之為run_process
。
為了描述run_process
,它是一個連續等待(無限循環/while True)文本輸入並進行文本預處理然后在 output 中打印預處理輸入的代碼:
我想知道我是否可以發出一些命令/請求以將輸入/STDIN 文本發送到此正在運行的進程並獲取 output 文本,目前我想避免編輯 run_process 並找到“外部”解決方案。
我嘗試了這里提出的解決方案: https://serverfault.com/a/178470並運行:
echo "test" > /proc/2657677/fd/0
echo "test\n" > /proc/2657677/fd/0
echo -ne "test\n" > /proc/2657677/fd/0
得到這個:
我沒有得到 output,就像它無法模擬 ENTER 鍵,甚至只是打印“輸入字符串”旁邊的文本,因為當我按下 ENTER 鍵時,output 中什么也沒有得到:
如果您對此有任何解決方案,即使使用 python 或任何其他語言,所有解決方案都會很有趣。
有關詳細信息,代碼 run_process 使用 c++ readline function:
char* input = readline("Input string: ");
第 90 行來自: https://opengrm.org/doxygen/thrax/html/rewrite-tester-utils_8cc_source.html#l00245要了解更多信息,您可以看到我稱為“run_process”的代碼實際上在第 247 行。
readline
庫所做的不僅僅是閱讀一行文本。 我不知道它在什么情況下做什么的確切規則,但它會檢測終端的存在,並在被告知時啟用諸如行編輯和命令行歷史記錄之類的功能。
如果啟動程序run_process
,它的stdin
和stdout
流通常連接到運行用於啟動程序的 shell 的終端。 這可能是一個真正的終端,或者現在更有可能是一個偽終端。 這樣的偽終端有一個主端,它由您正在使用的終端仿真器(例如 xterm)控制,還有一個客戶端,用作該終端中運行的前台進程的stdin
和stdout
。
如果您正在寫入/proc/.../fd/0
文件,則您正在寫入偽終端的客戶端。 這會繞過所有通常由偽終端驅動程序完成的終端功能。 而是在寫入數據時將其發送到進程。
readline
庫知道它連接到一個偽終端並使用它的功能來檢測 ENTER 鍵按下(這在 readline 中啟用多行“行”)。 這里的本質部分是, readline
不僅依賴於輸入字符 stream 進行換行,還依賴於(偽)終端功能。 這就是為什么直接寫入/proc/.../fd/0
(繞過這些功能)不能與readline
結合使用的原因。
現在我認為你有幾種選擇(可能有更多,但這些是我想到的):
不要使用readline
,而是直接從 stdin 讀取並在換行符上換行。 但是,您將失去readline
中所有很酷的功能。 如果您的程序設計為僅與生成的輸入一起使用,這可能不是問題,但如果程序還應該具有良好的交互式輸入功能,您可能不想沒有readline
。
不要為輸入 stream 使用偽終端。您可以改用例如這樣的 fifo 特殊文件
$ mkfifo myfifo $ tail -f myfifo |./run_process
並將數據發送到進程
$ echo "test" > myfifo
最后使用rm myfifo
再次刪除 fifo。 tail -f
命令用於在不同的echo
之間保持 fifo 打開。
使用像socat
這樣的工具來創建一個額外的偽終端,你可以在主端控制它:
$ tty $ socat STDIO,raw,echo=0 SYSTEM:./run_process,pty,stderr
並通過以下方式寫入流程
$ echo "test" > /dev/pts/<number_returned_by_the_above_tty_command>
使用socat
,您還有很多不同的選擇。 如果將STDIO
源更改為socat
的不同連接選項,則可以輕松地使run_process
程序偵聽 tcp 連接或 unix 域 sockets,這也可用於雙向數據傳輸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.