我想要做的是通过 SSH 反复发出命令。如果我执行以下操作,这会很好:
(ns bla
(:require [clj-ssh.ssh :as ssh]))
(defn poll [func]
(while true
(func)
(Thread/sleep 1000)))
(defn exec-on-ssh
"Connects to a host and then does there whatever the passed command dictates"
[host command]
(let [agent (ssh/ssh-agent {})
session (ssh/session agent host {:strict-host-key-checking :no})]
(ssh/with-connection session
(poll (fn [] (let [result (ssh/ssh session {:cmd command})]
(println (get result :out))))))))
; usage:
(exec-on-ssh "some-host" "uptime | sed s/^.*average:\\ //")
但后来我有了一个聪明的想法,那就是返回一个函数,我只需将命令和处理函数传递给它:
(defn exec-on-ssh
"Connects to a host and then does there whatever the passed command dictates"
[host]
(let [agent (ssh/ssh-agent {})
session (ssh/session agent host {:strict-host-key-checking :no})]
(ssh/with-connection session
(fn [command process-fun]
(while true
(let [result (ssh/ssh session {:cmd command})]
(process-fun (get result :out))))))))
; usage:
((exec-on-ssh "some-host") "uptime | sed s/^.*average:\\ //" println)
但这会引发以下异常:
JSchException Packet corrupt com.jcraft.jsch.Session.start_discard (Session.java:1050)
如果我理解正确,它会发生,因为当它执行任何操作时, session 已经消失了。经过一番试验,看起来这是因为
ssh/ssh
的关闭而发生的。 .有没有办法保持 session 并具有第二种方法提供的灵 active ?
最佳答案
你试过搬家吗with-connection
调用fn
?
此外,这可能并非以任何方式特定于 SSH。尝试编写一些代码,在 with-open
中构建和返回函数。 block ,文件将立即关闭with-open
退出。
我想引起注意的是 let
之间的区别。绑定(bind)和with-*
堵塞。后者是关于资源的,它们在执行主体后关闭资源。因此,在您的具体示例中,您创建了一个资源对象,您成功地创建了关闭该对象的函数。然后资源,这里的连接,被关闭。该函数仍然有对其的引用。它只是不再开放。
关于session - 通过 SSH session 关闭 - 这可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35174243/