Question

In clisp, the following code works:

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

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

Was it helpful?

Solution

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>

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top