我正在编写 SML 程序,我想要一种方法来快速查看在 REPL 中运行程序的输出,而无需实际运行 REPL(快速查看程序是否有语法错误 - 我计划将其用作 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
。相反,你是sml
管道的输出到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
或true
,或者仅重定向来自/dev/null
文件的输入。
echo -n | sml file.sml
sml file.sml < /dev/null