如何获取lein启动的子进程中Clojure代码监听的输入流?
解决子进程中Clojure代码的输入流传递问题
你踩的这个坑我之前也遇到过——lein run确实会偷偷启动一个额外的JVM进程来跑你的Clojure代码,而你现在通过ProcessBuilder拿到的输出流,其实只连到了bash和lein的启动进程,根本没碰着真正在执行(read-line)的那个子进程,输入当然传不进去啦。
给你两个实用的解决思路:
方案1:用lein trampoline run跳过中间进程
Leiningen的trampoline模式就是专门干这个的——它会启动你的Clojure代码进程后立刻退出,不会在中间占着坑。把你的启动命令改成这样就行:
(ProcessBuilder. (into-array ["bash" "-c" "cd some-folder ; lein trampoline run"]))
这下你往子进程OutputStream写的内容,就能直接传到(read-line)那里了。
方案2:绕过lein,直接用Java命令启动
如果不想依赖lein的trampoline特性,你可以先把目标项目编译好,直接用java命令运行:
- 先在
some-folder下执行lein compile编译代码 - 然后修改启动命令:
(ProcessBuilder. (into-array ["bash" "-c" "cd some-folder ; java -cp target/classes:$(lein classpath) your.main.namespace"]))
要是你已经打包成了独立的uberjar,那就更简单:
(ProcessBuilder. (into-array ["bash" "-c" "cd some-folder ; java -jar target/your-project-standalone.jar"]))
这种方式完全绕开了lein的中间进程,流的传递肯定没问题。
小补充
如果你的场景允许子进程直接用父进程的输入输出,也可以试试inheritIO(),不过这个可能不适合需要单独控制流的情况:
(doto (ProcessBuilder. (into-array ["bash" "-c" "cd some-folder ; lein trampoline run"])) .inheritIO .start)
内容的提问来源于stack exchange,提问作者Kevin Kostlan
相关产品推荐
相关产品推荐

