shell - clojure 中的 "inferior"进程 - 重定向异步输出以进行进一步处理

标签 shell clojure future

我想在 Clojure 中维护一个长时间运行的交互式 shell 进程——在 Emacs 中称为“劣质”进程。我认为基本思想很熟悉,因为 Clojure 本身可以通过 CIDER 在 Emacs 中运行。我很高兴知道是否有使用 Clojure 作为顶级流程的此设置的任何工作示例。

编辑:我发现了这个“shell”要点,这是一个非常漂亮的 Conch 包装器这让我深思。

用我自己的first attempt with Conch :我无法将字符串输入 python 并以与我相同的方式获取输出,例如 cat。但是通过一些实验,我弄清楚了基础知识并绕过了第一个障碍。

(require '[me.raynes.conch.low-level :as sh])
(def sh-python (sh/proc "python" "-i"))      ; "-i" needed to get interactive mode
#'flowrweb.core/sh-python
(future (sh/stream-to-out sh-python :out))   
#future[{:status :pending, :val nil} 0x516f3fff]
(sh/feed-from-string sh-python "1+1\n")      ; just returns nil on the CIDER repl
2                                            ; <- but we see "2" with the lein repl 
nil

所以我知道我感兴趣的数据是可用的,尽管它不在 CIDER 中打印有点奇怪(子问题...为什么不是 2打印?)。无论如何,对于我的用例,我不需要打印;相反,我只想将它作为字符串取回。

第一次尝试:

(def pyout (future (sh/stream-to-string sh-python :out)))
;=> #'flowrweb.core/py-out
(sh/feed-from-string sh-python "1+2\n")
;=> 3
;=> nil
@pyout
^C                     ; <- the process hangs

看来 sh/stream-to-string 并没有完全满足我的需要。

with-out-str 怎么样?

(def something (with-out-str (sh/feed-from-string sh-python "1+3\n")))
;=> 4
;=> #'user/something
something
;=> ""                 ;<- where is the "4"?

不,那也不起作用。

tl;dr:如何重定向 Conch 子进程的输出以供将来处理?

最佳答案

据我所知,没有用于管理流程的 Clojure 特定机制。此外,严格来说,操作系统进程不在 Clojure 的关注范围之内,因为它是一种托管语言,进程管理绝对是宿主应该管理的东西(例如 JVM 或 CLR)。

那么,假设您在 JVM 上运行 Clojure。 JVM 公开用于创建子进程的一种工具是 ProcessBuilder ,您可以从 Clojure 代码中调用它,就像下面这样 (credits go to @codification):

(ns proc
  (:import [java.lang ProcessBuilder])
  (:use [clojure.java.io :only [reader writer]]))

(defn spawn [& args]
  (let [process (-> (ProcessBuilder. args)
                  (.start))]
    {:out (-> process
            (.getInputStream)
            (reader))
     :err (-> process
            (.getErrorStream)
            (reader))
     :in (-> process
           (.getOutputStream)
           (writer))
     :process process}))

关于shell - clojure 中的 "inferior"进程 - 重定向异步输出以进行进一步处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39104127/

相关文章:

linux - 在不使用 awk 的情况下将对列表转换为 shell 中的表

linux - 需要 shell/perl 脚本来屏蔽 Linux 上日志文件中的敏感信息,如名字、出生日期、ssn 等

clojure - 为什么字符集看起来是有序的?

clojure - clojure 有原始字符串吗?

linux - 通过脚本验证 sudoing 密码

c - 通过 Sublime Text 输出 C/关闭命令控制台

clojure - 如何解释《Clojure 编程》一书中的 &env 示例

c++ - C++11 中的异步/ future 数量

scala - 处理Scala : Future For Comprehension时出错

java - 使用 Akka 远程系统玩 2.0.2