如何退出 REPL

38

我想退出REPL。

我尝试使用(. System exit 0)(System/exit 0),但会导致错误:

Exception in thread "Thread-3" java.lang.RuntimeException: java.lang.IndexOutOfBoundsException

有没有其他方法退出REPL?我该如何解决这个错误?


2
我想提出更具体的问题:如何使用代码而不是外部命令终止repl。 - Nevena
这个使用 java -jar clojure.jar 清理工作在 Clojure 1.11.0-master-SNAPSHOT 上是有效的。我猜在 Linux 版本或 Mac 的 brew 版本中需要使用 (exit) 以正常工作。 - Abdurrahman Adebiyi
11个回答

51
您可以发送“文件结束符”来退出。
您可以在REPL中按下ctrl-d(*nix)或ctrl-z(Windows)来退出。

谢谢回复。但我需要程序自动完成, 我的“archive.clj”有代码,在最后是(. System exit 0)。 - patz
1
@patz,为什么你在REPL模式下运行自动程序? - Robert P
不, 在 REPL 中键入 ctrl-d 也会关闭您运行 telnet 的终端。 - Phil Goetz
2
@PhilGoetz 我从未见过在Clojure REPL中使用ctrl-d会关闭它所在的终端(除非你是一个*nix用户,将lein repl作为他们的登录shell??)。 - Sean Corfield
我正在使用 PowerShell 的 Windows 系统,但 Ctrl-D 无法退出 Clojure repl :( - Michael Butler

29
我的回答已经有10年了,当时的语境理解较少(虽然我认为我和原问题提出者有相同的困惑,所以它还算有效)。
`System/exit 0`确实会退出整个JVM——这可能是你想要“退出REPL”的方式,但不一定是正确的方式。Clojure及其REPL是设计用于在多线程环境中运行的,甚至可以将多个REPL连接到同一个进程上。显然,如果你想要退出在其他继续进行的过程中的REPL,则退出JVM并不是你想要的。
以下是原始答案:
“看起来你的代码有不同的问题。”
“退出REPL的方法是:`(System/exit 0)`”
“另一种语法`(. System exit 0)`也可以使用。”
“你可以从干净的REPL中测试这个方法:`java -cp clojure.jar clojure.main -r`。”
“你得到的异常似乎表明在你的代码到达预期的退出点之前,在某些索引查找上出现了错误,很可能是在不同的线程上。”

我使用Linux终端在我的项目文件夹中使用-lein repl-开始repl。在src/myproject文件夹中,core.clj文件没有代码(并且是我的project.clj的:main)...当我启动repl时,我没有问题,立即写入(System / exit 0),但我遇到了错误 =/。 - patz
尝试在项目树之外进行一些操作。使用上面的普通Java命令和lein repl。 (您应该能够在没有任何项目设置的情况下获得repl)。您的项目代码或结构可能会导致问题。也许您有一些代码在调用主函数之前被评估。 - Alex Stoddard
我尝试使用一个空项目(只有放置lein的基本信息),当我写(System/exit 0)时,它给了我相同的错误,在没有项目的文件夹中(使用clojure.core的repl),退出没有问题。 - patz
1
看起来像是你的项目设置有问题。也许你可以将你的 project.clj 文件和其他文件粘贴到类似 https://gist.github.com/ 这样的网站上,否则我怀疑别人无法提供进一步的帮助。 - Alex Stoddard
最终我制作了jar文件,当我执行java -jar myproyect.jar时,(Syste.exit 0)没有任何问题。 - patz
显示剩余2条评论

8

(System/exit 0)的问题在于它会关闭整个JVM。真正的问题是如何以编程方式退出当前的repl,并返回启动该repl的任何函数。

以下是一个方便的解决方法:

(clojure.main/repl
  ; Exit the repl whenever the user enters "exit" at the prompt.
  :read (fn [request-prompt request-exit]
          (let [form (clojure.main/repl-read request-prompt request-exit)]
            (if (= 'exit form) request-exit form))))

clojure.main/repl 会默认使用 repl-read 函数来反复调用 reader 获取一个表单。reader 的一个参数是一个特殊的哨兵对象,当没有更多的表单需要读取时,reader 应该返回它。repl-read 函数仅在 EOF(文件结尾)时返回哨兵值。在 repl-read 提示符下,您无法访问哨兵对象,因此不能返回哨兵以告诉求值器您已完成输入表单。通过安装自己的 reader,您可以检查特定的表单 - 如符号 exit - 并在读取此表单时返回哨兵对象,从而告诉评估器您准备退出 repl,而不会杀死整个虚拟机。


7

我只是想退出REPL,结果来到了这里。

当我们开始在Clojure REPL中迈出第一步时,似乎每个人都会有这样的问题。当然,我没有阅读启动消息。对于我的Clojure 1.7.0版本,答案是(exit)或(quit),或者像其他回复中所述,使用Control-d。

nREPL server started on port 49276 on host 127.0.0.1 - nrepl://127.0.0.1:49276
REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_72-b15
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (exit)
Bye for now!

在我的 Mac 上,使用 brew 安装的 Clojure 版本 1.10.1 ,(exit) 失败并出现错误 user=> (exit) Syntax error compiling at (REPL:1:1). Unable to resolve symbol: exit in this context 。我不得不使用 ( (. System exit 0) 来退出。@andreas-guther 我看到你的代码中有头部 nREPL server,那么版本 1.7 及以下是否可以直接使用 exit - Abdurrahman Adebiyi
与OP有相同的问题。按下Ctrl-D的效果是让我退出了lein repl。谢谢。 - Austin

6

在emacs中退出Cider REPL,你可以使用以下按键组合:C-c C-q


(注:Cider是一款基于Clojure的开发环境)

1
真正的答案!!!因为他只是问如何退出,而不是如何退出和杀死! - rezwits

4
如果您安装了"lein",则可以像这样使用exitquit命令退出:
$ lein repl
...
user=>exit
Bye for now!

2
在Mac上,使用CTRL + C两次进行复制,如下图所示:

REPL Image


2

在 Linux 上安装 Clojure 1.10.2

(. System exit 0)

1

今天我有了答案,这就是我需要的。

(import ('java.lang.management ManagementFactory)
(use 'clojure.contrib.shell)
(defn process-pid [] (let [m-name (.getName (ManagementFactory/getRuntimeMXBean))] (first (.split m-name "@"))))

(defn exit (sh "kill" (process-pid))

1

退出repl: 如果您正在从命令行运行repl,则(如Sean所述)使用ctrl-d
如果您正在从slime运行它,则Alt-x slime-quit-lisp应该可以。 如果您正在从eclipse运行它,则我不确定是否有干净的退出方式请使用小红按钮。


谢谢回复。但我需要程序自动完成, 我的“archive.clj”有代码,在最后是(. System exit 0)。 - patz

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