【问题标题】:How does Erlang's Eshell keep the input line unaffected by async output?Erlang 的 Eshell 如何保持输入行不受异步输出的影响?
【发布时间】:2014-11-29 15:40:36
【问题描述】:

我想用 Erlang 以外的另一种语言实现 REPL,我对交互式 erl (Eshell) 提示符的这一特性非常感兴趣:

1> spawn(fun() -> timer:sleep(5000), io:format("~p~n", ["later"]) end).
<0.34.0>
2> i can ty

所以我在这里所做的是生成一些最终写入终端的后台进程。与此同时,我刚刚输入了i can ty,五秒钟过去了,"later" 被插入到2&gt; 的正上方,结果是:

1> spawn(fun() -> timer:sleep(5000), io:format("~p~n", ["later"]) end).
<0.34.0>
"later"      
2> i can type...

在其他语言中,例如 Bash 或 Node.js,这宁愿产生类似的结果:

2> i can ty"later"
pe...

Erlang 是如何做到这一点的?我试过用谷歌搜索,甚至快速浏览了它的源代码,但不知道这是如何完成的。我认为它必须涉及一些终端控制序列?

【问题讨论】:

  • 这不是一个简单的问题,老实说你可能在这里找不到答案。如果你真的有兴趣,你可以点击 erlang mailig list,所有酷猫都在那里闲逛:erlang-questions@erlang.org
  • 写入标准输出是由一个进程完成的。发送给它的消息可能会被 shell 拦截。

标签: erlang erl


【解决方案1】:

Erlang shell 比其他语言更复杂,因为它必须与具有许多进程的分布式系统一起工作。 Fred Hebert 写了一篇关于 Erlang shell 的文章,名为“As bad as anything else”。

基本上,当您拨打io:format 时,它会向其组长发送一条消息。在“Learn you some Erlang/Building OTP applications”(同样是 Fred)中,有一条关于组长和io protocol 的注释。

正如@rightfold 在他的评论中提到的,io_protocol 涉及发送消息。这意味着,它们按顺序写入控制台。在其他语言中,如果您有更多进程同时写入,则可以将部分消息交错,但在 Erlang 中则不行。该协议还涉及等待​​回复。例如检查io:execute_requeston github

user_drv 负责将消息写入实际的tty 并使用ncurses 将其放在它想要的位置,因此它可以在您开始编写的命令之前插入消息,从而留下干净的历史记录。

【讨论】:

  • 谢谢。我认为它对ncurses 的使用是这里的一个关键见解。
猜你喜欢
  • 2018-08-17
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 2021-07-15
  • 1970-01-01
相关资源
最近更新 更多