如何在GHCI中终止执行?

22

当我启动时

ghci> last [0..]

我可以使用Ctrl+C来中断它。

然而

ghci> last (repeat 0)

无法使用 Ctrl+C 中断。GHCI 会默默地忽略这些按键。

如何在 GHCI 中中断该命令?这是一个 bug 吗?


我也注意到了这一点,所以我很高兴能看到答案。也许这是一个 bug? - AJF
8
我担心后一个命令从未分配内存。在这种情况下,GHC线程调度程序不公平(如果我没记错的话),将永远不会将控制权转移到其他线程,也不会允许来自Ctrl-C的异步异常被传递。(说实话,很久以前是这种情况,我不知道他们是否已经解决了这个问题。) - chi
我知道你所说的问题,但至少对于我(在GHC-7.10中),Ctrl+C确实会中断last (repeat 0) - Daniel Wagner
3个回答

15

您可以使用:quit命令退出GHCI。

Prelude> :quit
Leaving GHCi.

或者按下Control+D来发送EOF信号,详见

如果GHCI正在忙碌中,则除了手动结束该进程外,您别无选择。


1
为什么这不是一个答案? - gavrilikhin.d
1
@gavrilikhin.d 因为它依赖于 ghci 响应。整个问题是关于当 ghci 不能正常响应时该怎么办的。 - Daniel Wagner
@DanielWagner,是的,我错过了这一部分,因为我正在寻找简单退出ghci的方法XD。 - gavrilikhin.d

14
(读者注意:我使用Linux,在urxvt或gnome-terminal上运行zsh。如果您使用不同的操作系统、终端或shell,这可能会对您产生不同的影响。)
我通常处理这种情况的方式是按下Ctrl+Z键(将其放在后台,暂停执行作为副作用),然后杀死该进程。通常情况下,这是通过kill %1来完成的,但您可以运行jobs进行双重检查。
您还可以启动一个新的终端并执行killall -9 ghci之类的操作,但这将导致更高的资源成本:您正在生成一些新的进程,打开X连接,执行初始化时终端所需的所有操作,执行初始化时shell所需的所有操作等。如果您处于我经常遇到的情况——ghci正在频繁交换——那么这只会让ghci有更多时间搞砸事情。
如果您能预测此问题,并且正在编译,则可以使用-fno-omit-yields来要求GHC在紧密的、非分配循环内部插入Ctrl+C检查。

4
< p > Ctrl+Z 看起来离开了 shell,但它并没有完全关闭进程。

例如

$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude> 
[4]+  Stopped                 ghci
$ ps
  PID TTY          TIME CMD
 3160 pts/1    00:00:00 bash
 3554 pts/1    00:00:21 emacs
 5602 pts/1    00:00:00 ghc
 5693 pts/1    00:00:00 ps

然而,如果您执行Ctrl+D
$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude> 
Leaving GHCi.
$ ps
  PID TTY          TIME CMD
 3160 pts/1    00:00:00 bash
 3554 pts/1    00:00:21 emacs
 5870 pts/1    00:00:00 ps

因此,关闭的正确方式是按下键。

: 在Linux(Ubuntu 16.04 LTS)上进行测试。


2
在执行代码时,按下Ctrl+D不会关闭ghci。另一方面,Ctrl+Z发送一个信号,该信号无法被接收进程捕获或处理,因此始终有效(对于任何进程,而不仅仅是ghci)。您可以使用kill或类似工具清理Ctrl+Z留下的剩余进程,如我的答案所述。 - Daniel Wagner
是的...当我让它计算333^333^333时,Ctrl+D并没有关闭我的ghci - Student

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接