Does there exist standard way to run external program in Common Lisp?

前端 未结 6 1621
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-11 15:07

In clisp, the following code works:

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

However, in Clozure CL, the shell fu

相关标签:
6条回答
  • 2021-01-11 15:42

    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))
    
    0 讨论(0)
  • 2021-01-11 15:50
    (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

    0 讨论(0)
  • 2021-01-11 15:55

    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.

    0 讨论(0)
  • 2021-01-11 15:58

    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*) 
    
    0 讨论(0)
  • 2021-01-11 16:02

    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>
    
    0 讨论(0)
  • 2021-01-11 16:05

    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
    0 讨论(0)
提交回复
热议问题