Does there exist standard way to run external prog

2019-02-16 14:21发布

问题:

In clisp, the following code works:

(defun hit-history () (shell "tail ssqHitNum.txt"))

However, in Clozure CL, the shell function is not supported!

回答1:

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>


回答2:

  • synchronous commands: uiop:run-program (documentation in source)
  • asynchronous commands: uiop:launch-program (documentation in source)

(edit jan 18) 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.

For asynchronous shell commands, see uiop's launch-program.



回答3:

(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



回答4:

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*) 


回答5:

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))


回答6:

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