繁体   English   中英

如何从Clojure内部运行交互式CLI程序?

[英]How to run an interactive CLI program from within Clojure?

我想从Clojure(例如vim)中运行一个交互式CLI程序,并能够与其交互。

在bash和其他编程语言中,我可以使用

vim > `tty`

我试图在Clojure中做同样的事情:

(require '[clojure.java.shell :as shell])
(shell/sh "vim > `tty`")

但是它只是打开vim而没有给我tty。


背景:我正在开发一种Clojure CLI工具,该工具可以解析电子邮件,并允许用户编辑已解析的数据,然后再将其保存到磁盘上。 它的工作方式如下:

  1. 读取包含电子邮件内容的文件并进行解析。 每封电子邮件都存储为单独的文件。
  2. 向用户显示已解析的数据,并让用户在vim中编辑数据。 在内部,我使用已解析的数据创建一个临时文件,但是如果可以解决我的问题,我不介意以其他方式进行操作。
  3. 用户完成对已解析数据的编辑(他们可能决定保留原样)后,将数据追加到磁盘上的文件中。 因此,所有解析的数据都保存到同一文件中。
  4. 如果还有电子邮件剩余的文件,请转到第一步。

此代码依赖于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM