Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

117 lines (82 sloc) 3.177 kb


SSH in clojure. Uses jsch.



The clj-ssh.cli namespace provides some functions for ease of use at the REPL.

(use 'clj-ssh.cli)

Use ssh to execute a command, say ls, on a remote host "my-host",

(ssh "my-host" "ls")
  => {:exit 0 :out "file1\nfile2\n" :err "")

By default this will use the system ssh-agent to obtain your ssh keys, and it uses your current username, but this can be specified:

(ssh "my-host" "ls" :username "remote-user")
  => {:exit 0 :out "file1\nfile2\n" :err "")

Strict host key checking can be turned off:

(default-session-options {:strict-host-key-checking :no})

SFTP is also supported. For example, to copy a local file to a remote host "my-host":

(sftp "my-host" :put "/from/this/path" "to/this/path")

Note that any sftp commands that change the state of the sftp session (such as cd) do not work with the simplified interface, as a new session is created each time.

If your key has a passphrase, you will need to explicitly add your key either to the system's ssh-agent, or to clj-ssh's ssh-agent with the appropriate add-identity call.


The clj-ssh.ssh namespace should be using SSH from functional code.

(let [agent (ssh-agent {:use-system-ssh-agent false})]
  (add-identity agent "/user/name/.ssh/id_rsa")
  (let [session (session agent "localhost" {:strict-host-key-checking :no})]
    (with-connection session
      (let [result (ssh session {:in "echo hello"})]
        (println (result :out)))
      (let [result (ssh session {:cmd "ls"}]
        (println (second result))))))

The above example shows using :in to pass commands to a shell, and using :cmd to exec a command without a shell. When using :cmd you can still pass a stream or a string to :in to be used as the process' standard input.

(let [agent (ssh-agent {})]
  (let [session (session agent "localhost" {:strict-host-key-checking :no})]
    (with-connection session
      (let [channel (ssh-sftp session)]
        (with-channel-connection channel
          (sftp channel :cd "/remote/path")
          (sftp channel :put "/some/file" "filename"))))))

SSH tunneling is also supported:

    (let [agent (ssh-agent {:use-system-ssh-agent false})]
      (let [session (session agent "localhost" :strict-host-key-checking :no)]
        (with-connection session
          (with-local-port-forward [session 8080 80]
            (comment do something with port 8080 here)))))


Annotated source. API.


Q: What does "4: Failure @ com.jcraft.jsch.ChannelSftp.throwStatusError(" during an sftp transfer signify?

A: Probably a disk full, or permission error.


Via clojars and Leiningen.

:dependencies [clj-ssh "0.4.0-SNAPSHOT"]

or your favourite maven repository aware tool.


Copyright © 2012 Hugo Duncan

Licensed under EPL

Jump to Line
Something went wrong with that request. Please try again.