如何在lisp中与ssh会话进行交互?

时间:2011-12-07 22:46:30

标签: ssh stream common-lisp clisp

我想使用常见的lisp来编写脚本,并通过ssh连接到远程计算机并发送一些命令。最简单的方法似乎是使用clisp的ext:run-shell-command,文档here,然后读取和写入结果流。如果有更好的方式让我知道。当我尝试这个时:

[5]> (setf shell-str (ext:run-shell-command "ssh remotecomp" :input :stream :output :stream)) 

#<IO TWO-WAY-STREAM #<INPUT BUFFERED PIPE-INPUT-STREAM CHARACTER 1204> #<OUTPUT BUFFERED PIPE-OUTPUT-STREAM CHARACTER 1204>>
[6]> Pseudo-terminal will not be allocated because stdin is not a terminal.

inferior-lisp-buffer 中的进程挂起并且必须用C-c c杀死。但是shell-str对象确实被创建了,但是当我尝试从它读取时,那里没有输出。

[9]> (read-line shell-str)

*** - READ: input stream
       #<IO TWO-WAY-STREAM #<INPUT BUFFERED PIPE-INPUT-STREAM CHARACTER 1204>
         #<OUTPUT BUFFERED PIPE-OUTPUT-STREAM CHARACTER 1204>>
      has reached its end
The following restarts are available:
ABORT          :R1      Abort main loop

使用类似“ls -l”的运行ext:run-shell-command确实可以正常工作。在cygwin或甚至Windows命令提示符下运行ssh可以正常工作。我在Windows 7上运行clisp 2.49和openssh 5.9p1。

编辑:通过对ssh使用无密码和双-t参数来实现它。

(setf str (ext:run-program "ssh" :arguments '("-t" "-t" "host") :output :stream :input :stream))
(format str "ls -l~%")
(finish-output str)
(read-line str)

1 个答案:

答案 0 :(得分:1)

Snowape找到了clisp的解决方案。这是CCL解决方案的工作版本:

? (run-program "ssh" '("-t" "-t" "[user]@[ip]") :output :stream :input :stream :wait nil)
#<EXTERNAL-PROCESS (ssh -t -t ...)[65909] (RUNNING) #x302000A2335D>
? (setf *t* *)
#<EXTERNAL-PROCESS (ssh -t -t ...)[65909] (RUNNING) #x302000A2335D>
? (setf *in* (external-process-input-stream *t*))
#<BASIC-CHARACTER-OUTPUT-STREAM ISO-8859-1 (PIPE/17) #x302000A2304D>
? (setf *out* (external-process-output-stream *t*))
#<BASIC-CHARACTER-INPUT-STREAM ISO-8859-1 (PIPE/18) #x302000A22ABD>
? (read-line *out*)
"Last login: ...
NIL
? (read-line *out*)
"Have a lot of fun...
NIL
? (format *in* "ls -l~%")
NIL
? (finish-output *in*)
NIL
? (read-line *out*)
"user@ip:~> ls -l
NIL
? (read-line *out*)
"total 0
[etc.]

作为替代方法,您可以使用Quicklisp加载Trivial Shell程序包,然后从执行脚本的lisp会话中启动shell进程(将在其中包含ssh命令)。我从未在Windows中试过Trivial Shell,所以不确定它会如何表现。