如何从Clojure命令行应用程序中放入repl?
我正在编写一个Clojure CLI应用程序,我想允许向它发出一个命令,该命令会将用户放入Clojure.main REPL 有人知道我该怎么做吗?我的努力没有取得成果 编辑: 我的CLI采用管道输入这一事实使我的问题更加严重。下面是我想从事的工作的一个例子:如何从Clojure命令行应用程序中放入repl?,clojure,command-line-interface,read-eval-print-loop,Clojure,Command Line Interface,Read Eval Print Loop,我正在编写一个Clojure CLI应用程序,我想允许向它发出一个命令,该命令会将用户放入Clojure.main REPL 有人知道我该怎么做吗?我的努力没有取得成果 编辑: 我的CLI采用管道输入这一事实使我的问题更加严重。下面是我想从事的工作的一个例子: (ns playground.core (:gen-class)) (defn -main [& args] (with-open [r (io/reader *in*)] (doseq [line (lin
(ns playground.core
(:gen-class))
(defn -main
[& args]
(with-open [r (io/reader *in*)]
(doseq [line (line-seq r)]
(println line)))
;; Drop in repl after having read the input and printed its content)
那么我就这样称呼它:
cat ./somefile.txt | lein trampoline run
您只需从程序中调用
clojure.main/repl
,它就会开始收听stdin并对其进行“回复”;-)此时,repl将启动
user> (clojure.main/repl)
然后我在终端中键入(+1 2 3)
因此,我在repl中设置了一个repl,用于模拟使用您的程序的人键入start repl命令的情况
为了获得人性化的repl体验,该项目为调用clojure.main/repl添加了很多内容:
(rebel-readline.core/with-line-reader
(rebel-readline.clojure.line-reader/create
(rebel-readline.clojure.service.local/create))
(clojure.main/repl
:prompt (fn []) ;; prompt is handled by line-reader
:read (rebel-readline.clojure.main/create-repl-read)))
由于您的计划基本上分为两个阶段
中突破出来。收到后,完全退出行序列
并打开。然后启动repl,以便它可以获取输入文件描述符。
一旦您使程序获得repl的输入,您的管道问题就可以在封闭的shell命令中得到解决cat
采用一个特殊参数-
(只有一个破折号,两侧没有空格),该参数表示“停在此处,从键盘读取,直到按下Crtl-d”
在本例中,它从一个文件中读取一行,将其传递给cat命令(替换为您的程序),然后从键盘读取单词hello
,并将其打印出来(因此您在屏幕上会看到两次)可能启动一个headless REPL并执行两个单独的步骤可能对您有效
步骤1
启动一个无头REPL,等待它启动
$ lein repl :headless :host 0.0.0.0 :port 9000
nREPL server started on port 9000 on host 0.0.0.0 - nrepl://0.0.0.0:9000
步骤2
在另一个shell中,使用以下命令将命令发送到REPL:
$ cat test.txt
(def hello "Hello world!")
$ cat test.txt | lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
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
pipetest.core=> (def hello "Hello world!")
#'pipetest.core/hello
pipetest.core=> Bye for now!
步骤3
您可以连接到REPL,在状态从上一步更改后继续,但现在您可以使用它进行交互
$ lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
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
pipetest.core=> (str hello "!!!")
"Hello world!!!!"
我不认为这是重复的,因为这个问题没有解决repl不需要是程序输入的第一个消费者,也不需要在程序启动时启动的问题。是的,我的问题是特别试图得到一个答案,其中repl不是第一个启动的。程序首先启动,接受in的输入,执行更多操作,然后需要转换为REPL。CLI REPL在stdin和stdout上运行,管道也一样。也许您应该将nREPL/socket REPL与pREPL一起使用并远程连接?这将使您的stdin为文件管道打开,但允许您远程连接REPL。或者,你可以阅读stdin,然后像其他答案中提到的那样开始一个REPL。@Olical我可以走这条路,但问题是,当我在REPL中输入stdin时,我已经完成了。但似乎是stdin导致REPL在启动后立即关闭。我将输入导入Clojure CLI。例如cat somefile.txt | lein蹦床跑
。在这种情况下,调用clojure.main/repl
或使用rebel readline都不起作用。如果我不使用管道输入,只运行lein trampoline run
,它确实可以工作。知道我如何在管道输入的情况下进入repl吗?@DidierA。添加了关于绕过管道输入的内容,以及关于将其从读取行中分离出来的一些意见
$ cat test.txt
(def hello "Hello world!")
$ cat test.txt | lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
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
pipetest.core=> (def hello "Hello world!")
#'pipetest.core/hello
pipetest.core=> Bye for now!
$ lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
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
pipetest.core=> (str hello "!!!")
"Hello world!!!!"