Как я могу подписаться (построчно) на вывод команды блокирующей оболочки в Clojure? - PullRequest
4 голосов
/ 26 мая 2020

По сути, я хочу захватить первую строку вывода (FIFO) команды оболочки в каком-то объекте, будь то атом или chan. Я просмотрел core.cache и core.asyn c, но мне еще не удалось найти ничего, что могло бы решить проблему, заключающуюся в том, что sh (из clojure.java.shell) возвращает значение только тогда, когда команда перестала писать в стандартный вывод. Как я могу получить доступ к данным, которые он передает по мере их поступления? Например, я хотел бы иметь объект, который имеет самую последнюю строку вывода bspc subscribe, pactl subscribe или что-то подобное.

Для контекста я написал конфигурацию для лимонбара, строки состояния, которая читает со стандартного ввода и записывает в стандартный вывод. В настоящее время у меня есть набор Thread, которые спят в течение 100 мс и обновляют вывод таких вещей, как wmctrl -d, mpc current и т. Д. Вместо этого я хотел бы подписаться на эти события, как на Bash (bspc subscribe | while read line ...).

Спасибо.

1 Ответ

2 голосов
/ 26 мая 2020

В этом решении используются [com.kohlschutter.junixsocket/junixsocket-core "2.3.2"] и [me.raynes/fs "1.4.6"].

(ns so.unix-socket
    (:require
        [me.raynes.fs :as fs]
        [clojure.java.io :as io])
    (:import
        (org.newsclub.net.unix AFUNIXServerSocket AFUNIXSocketAddress)))


(def file-name (fs/temp-file "abc"))
(.deleteOnExit file-name)
(def file (io/file file-name))

(def server (doto (AFUNIXServerSocket/newInstance)
                (.. (bind (AFUNIXSocketAddress. file)))
                (.. (setSoTimeout 10000))))

(future
    (let [socket (.. server (accept))
          rdr    (io/reader (.getInputStream socket))]
        (loop [line (.readLine rdr)]
            (when (some? line)
                (println line)
                (recur (.readLine rdr))))))

(clojure.java.shell/sh "bash" "-c"
    (format "pactl subscribe|socat STDIN UNIX-CONNECT:%s"
            (.getAbsolutePath file-name)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...