
我正在編寫 SML 程序,並且我想要一種方法來快速查看在 REPL 中運行程序的輸出,而無需實際運行 REPL(快速查看程序是否有語法錯誤 - 我計劃將其用作 make vim 中的.sml文件程式以查看vim 內的輸出)..目前,我有這個:
sml file.sml | echo -e "\004"
因此它運行該程序,然後回顯 Ctrl-D 退出 REPL。問題是發送 Ctrl-D 鍵太快,因此沒有輸出。我也嘗試過這個:
sml file.sml | sleep 2 ; echo -e "\004"
但這也沒有做到這一點。關於如何從 REPL 獲取輸出轉儲有什麼想法嗎?
答案1
不,問題是您誤解了管道的工作原理。
在 Unix 管道中,資料流從左到右(與英文書寫文字方向相同) - 第一個程式的輸出成為第二個程式的輸入。但管道是單向的;第二個程式的輸出不會送到第一個程式。
當你跑步時sml file.sml | echo -e "\004"
,你不是將 Ctrl+D 回顯到sml
.相反,你是Pipelinesml
的輸出到echo
指令– 它被丟棄的地方,因為echo
不使用標準輸入。
- 鍵盤 →
sml file.sml
→echo -e "\004"
→ 螢幕
您的第二次嘗試,sml file.sml | sleep 2 ; echo -e "\004"
,有類似的問題 - 的輸出sml
被發送到sleep
(它也會丟棄它收到的輸入)。然而,還有另一個問題:該echo
命令現在根本不是管道的一部分;你可以說 比|
具有更高的優先權;
。 (你可以使用括號對命令進行分組;例如a | (b; c; d)
。
- 鍵盤 →
sml file.sml
→sleep 2
→ 螢幕 - 鍵盤 →
echo -e "\004"
→ 螢幕
正如上面已經說過的,這兩種嘗試都寫在方向錯誤。如果你想將\004
字元送到sml
,管道應該這樣寫:
echo -e "\004" | sml file.sml
其中,sml
的輸出將輸出到螢幕上應有的位置。
有另一個問題, 然而。你也是CtrlD將按鍵與「輸入結束」混淆事件。
到「輸入結束」的轉換CtrlD僅發生在終端機設備層 - 換句話說,僅當您在終端機視窗中輸入 Ctrl+D 字元時發生。但是,當您echo -e "\004"
在管道中使用時,它是不是自動翻譯為“輸入結束”;相反,寫入的是實際位元組 004 [八進位]。
如果你想真正告訴程式沒有更多的輸入,那麼不要寫任何東西。使用不輸出任何內容的命令 - 例如,echo -n
or true
,或僅重定向/dev/null
檔案中的輸入。
echo -n | sml file.sml
sml file.sml < /dev/null