In clisp, the following code works:
(defun hit-history () (shell "tail ssqHitNum.txt"))
However, in Clozure CL, the shell
function is not supported!
In clisp, the following code works:
(defun hit-history () (shell "tail ssqHitNum.txt"))
However, in Clozure CL, the shell
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>
trivial-shell
is deprecated and replaced by inferior-shell, which simply uses uiop run-program
(sync). For async, see uiop's launch-program
. –
Wiley Yes, with UIOP, part of ASDF, that should be included in all modern implementations.
uiop:run-program
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
(sb-ext:run-program "/usr/bin/dot" (list "-Tpng" "-O" fname)))
–
Miterwort 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.
© 2022 - 2024 — McMap. All rights reserved.
trivial-shell
library. Also, I'm not sure the reasoning behind the "read-time conditionals" suggestion, since that is exactly what trivial-shell does. (That's why such libraries are called trivial-*.) – Profligate