簡體   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