linux - 在 Linux 上的 ghci 中读取标准输入被破坏

标签 linux bash haskell

来自 Windows,我最近通过 bash (ghc 7.10) 安装了名为 Peppermint 和 Haskell-Platform 的 Linux 发行版,但是 ghci 中的 ghci stdin 一定有问题,因为:

交互 $ 取 0 抛出错误但是 互动 $ take 1 没有。

此外,如果我在写入 stdin 时使用 backspacearrows 或任何其他控制按钮,它会输入 char 符号。例如退格键^?输入ghci而不是删除最后输入的字符...

...@... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude> interact $ take 0
Prelude> 
<stdin>: hGetChar: illegal operation (handle is closed)
...@... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude> readLn :: IO String 
euoe^?^?^[[1;5C^[[D^[[B -- here I tried to delete 'euoe'

最佳答案

关于控制代码文字,这是因为您已经设法转义了通常会解释您的按键操作的所有行编辑器(readline、Haskeline)。

我不知道细节,但调用 GHCi 就像使用 bash --noediting 启动子 shell。这允许 GHCi 接收原始按键而不受 readline 库的干扰。这样做是因为 Haskeline(GHCi 使用它代替 readline)可以更轻松地配置可用功能的制表符完成之类的东西(您知道 GHCi 提供制表符完成,对吧?)。

然后从 GHCi 调用 getLine 有效地穿过陷阱门并通过直接进入 stdin 来完全避开 Haskeline。毕竟,只有一个标准输入。您现在正在直接向无缓冲终端输入。

回到您的第一个问题,只有一个标准输入也是 GHCi 在打印 Prelude> 提示后立即崩溃的原因。 interact(在幕后使用 hGetContents)声称它将处理所有将通过句柄 (stdin) 传入的输入作为一个大的惰性 String 。实际上,interact 尚未声明要处理的句柄上没有剩余输入,因此句柄会立即进入“半关闭”状态。它没有关闭(仍然可能有更多的输入将被读取为惰性 String interact 获取的一部分!)但它已关闭任何新来者,否则输入将被重复(interact 和 handle 的新读者,例如 getLine 将获得相同的行!)。

回到 GHCi,在使用 interact 之后,stdout 仍然可以正常打印提示,然后 GHCi 依靠 Haskeline 返回一行进行处理。 Haskeline(作为行编辑器)调用阻塞 getChar (iirc) 来向行添加字符或执行一些行编辑命令并死掉,因为它正在寻址半封闭句柄。因此,一个较弱的生物确实倒下了,而生命的巨轮继续滚动。

关于linux - 在 Linux 上的 ghci 中读取标准输入被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38816153/

相关文章:

linux - Hadoop错误日志jvm sqoop

c++ - firebreath npplugin 中的文件写入权限被拒绝

Python 和 pymysql - 无法通过 MySQL 执行系统命令

git - 如何在 Git Bash for Windows 中设置别名?

haskell - 将字典变成约束

Python + Linux : How to determine cron job is scheduled?

ruby - #!/usr/bin/env ruby​​ 在 cron 中找不到

linux - 在 Linux 中同步目录内容

haskell - 用 Haskell 编码 "Less Than"

haskell - 使用遍历实现 sequenceA