2016-02-03 69 views
1

我想要做的是通過SSH重複發出命令。如果我做這工作就好了以下內容:通過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) 

如果我正確地理解了這一點,它發生的原因是,當它執行任何操作時,會話已經消失。經過一番試驗,看起來像是因爲ssh/ssh關閉而發生的。

有沒有辦法讓會話具有第二種方法所提供的靈活性?

回答

2

您是否嘗試過移動with-connection致電fn

此外,這可能不是特定於SSH的任何方式。嘗試編寫一些在with-open塊內構建並返回函數的代碼,該文件將在退出with-open時關閉。

我想提請注意的是let綁定和with-*塊之間的區別。後者是關於資源的,並且在他們的身體被執行後關閉資源。因此,在您的具體示例中,您將創建一個資源對象,並使用關閉此對象的函數成功創建。然後關閉此處的資源和連接。該功能仍然有其參考。它不再是開放的。

+0

是的,這是我的愚蠢 - 我沒有返回我期望返回的函數。隨着改變你建議它的工作。 – dezso