Does there exist standard way to run external program in Common Lisp?
In clisp, the following code works:
(defun hit-history () (shell "tail ssqHitNum.txt"))
However, in Clozure CL, the she开发者_如何学Goll
function is not supported!
No, there is no standard way, but there are libraries which provide this functionality for the important implementations. For example, there's trivial-shell available in Quicklisp, which provides shell-command
. (I didn't actually test it, but its among the recommended libraries on CLiki.) There is also external-program. Update: inferior-shell seems to be prefered these days, as Ehvince points out in a comment and his own answer.
You could also use read-time conditionals to make different implementations use their respective functionality to do this.
CCL has ccl:run-program
, for example:
CL-USER> (run-program "whoami" '() :output *standard-output*)
foobar
#<EXTERNAL-PROCESS (whoami)[NIL] (EXITED : 0) #xC695EA6>
Yes, with UIOP, part of ASDF, that should be included in all modern implementations.
- synchronous commands:
uiop:run-program
- asynchronous commands:
uiop:launch-program
So for example
(uiop:run-program (list "firefox" "http:url") :output t)
or
(defparameter *shell* (uiop:launch-program "bash" :input :stream :output :stream))
where you can send input and read output.
They are more explained here: https://lispcookbook.github.io/cl-cookbook/os.html#running-external-programs
trivial-shell
is deprecated and replaced by inferior-shell, which internally uses the portable uiop's run-program
(synchronous), so we can use just that.
(defun dot->png (fname thunk)
(with-open-file (*standard-output*
fname
:direction :output
:if-exists :superseded)
(funcall thunk))
(ccl:run-program "dot" (list "-Tpng -O" fname))
)
i run success in ccl(clozure),when study land of lisp p123
The following shows an example of calling wget from within common lisp:
https://diasp.eu/posts/1742240
Here's the code:
(sb-ext:run-program "/usr/bin/wget" '("-O" "<path-to-output-file>" "<url-link>") :output *standard-output*)
Have a look at the inferior-shell
package.
(Get it via the almighty quicklisp
package manager.)
This works in the interpreter, if you have internet:
(require 'inferior-shell)
(inferior-shell:run/s '(curl icanhazip.com))
CL21 defines simple methods:
(in-package :cl21-user)
(use-package :cl21.process)
Then either with run-process
or with the #` reader macro:
(run-process '("ls" "-l"))
;-> total 0
; drwxrwxrwt 5 root wheel 170 Nov 1 18:00 Shared
; drwxr-xr-x+ 174 nitro_idiot staff 5916 Mar 5 21:41 nitro_idiot
;=> #<PROCESS /bin/sh -c ls -l /Users (76468) EXITED 0>
or
#`ls -l /Users`
;=> "total 0
; drwxrwxrwt 5 root wheel 170 Nov 1 18:00 Shared
; drwxr-xr-x+ 174 nitro_idiot staff 5916 Mar 5 21:41 nitro_idiot
; "
; ""
; 0
The source shows implementation for SBCL and CCL.
- http://cl21.org/
- https://github.com/cl21/cl21/wiki
- https://lispcookbook.github.io/cl-cookbook/cl21.html
精彩评论