[英]How to run an interactive CLI program from within Clojure?
I'd like to run an interactive CLI program from within Clojure (eg, vim) and be able to interact with it. 我想从Clojure(例如vim)中运行一个交互式CLI程序,并能够与其交互。
In bash and other programming languages, I can do that with 在bash和其他编程语言中,我可以使用
vim > `tty`
I tried to do the same in Clojure: 我试图在Clojure中做同样的事情:
(require '[clojure.java.shell :as shell])
(shell/sh "vim > `tty`")
but it just opens vim without giving me tty. 但是它只是打开vim而没有给我tty。
Background: I'm developing a Clojure CLI tool which parses emails and lets a user edit the parsed data before saving them on the disk. 背景:我正在开发一种Clojure CLI工具,该工具可以解析电子邮件,并允许用户编辑已解析的数据,然后再将其保存到磁盘上。 It works the following way:
它的工作方式如下:
This code relies on Clojure Java interop to make use of Java's ProcessBuilder
class. 此代码依赖于Clojure Java互操作来利用Java的
ProcessBuilder
类。
(defn -main
[]
;use doseq instead of for because for is lazily evaluated
(doseq [i [1 2 3]]
;extract current directory from system variable
(let [file-name (str "test" i ".txt")
working-directory (trim-newline (:out (sh "printenv" "PWD")))]
(spit file-name "")
;this is where fun begins. We use ProcessBuilder to forward commands to terminal
;we pass a list of commands and their arguments to its constructor
(let [process-builder (java.lang.ProcessBuilder. (list "vim" (str working-directory "/" file-name)))
;inherit is a configuration constant
inherit (java.lang.ProcessBuilder$Redirect/INHERIT)]
;we configure input, output and error redirection
(.redirectOutput process-builder inherit)
(.redirectError process-builder inherit)
(.redirectInput process-builder inherit)
;waitFor used to block execution until vim is closed
(.waitFor (.start process-builder))
)
;additional processing here
)
)
;not necessary but script tends to hang for around 30 seconds at end of its execution
;so this command is used to terminate it instantly
(System/exit 0)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.