Running shell commands with gnu clisp

I am trying to create a "system" command for clisp that works like this

(setq result (system "pwd")) ;;now result is equal to /my/path/here 

I have something like this:

 (defun system (cmd) (ext:run-program :output :stream)) 

But I'm not sure how to convert a stream to a string. I looked at the hyperscript and Google more than a few times.

edit: working with the Ranier team and using with-output-to-stream,

 (defun system (cmd) (with-output-to-string (stream) (ext:run-program cmd :output stream))) 

And then try to run grep , which is in my path ...

 [11]> (system "grep") *** - STRING: argument #<OUTPUT STRING-OUTPUT-STREAM> should be a string, a symbol or a character The following restarts are available: USE-VALUE :R1 Input a value to be used instead. ABORT :R2 Abort main loop Break 1 [12]> :r2 
+4
source share
4 answers

Something like that?

Version 2:

 (defun copy-stream (in out) (loop for line = (read-line in nil nil) while line do (write-line line out))) (defun system (cmd) (with-open-stream (s1 (ext:run-program cmd :output :stream)) (with-output-to-string (out) (copy-stream s1 out)))) [6]> (system "ls") "#.emacs# Applications ..." 
+5
source

In the CLISP documentation for run-program argument :output must be one of

  • :terminal - is written to the terminal
  • :stream - creates and returns an input stream from which you can read
  • path pointer - writes to the specified file
  • nil - ignores output

If you want to collect the output into a string, you will have to use a copy-write cycle to transfer data from the returned stream to the string. You already have a with-output-to-string in the game, as suggested by Rainer, but instead of providing this run-program output stream, you will need to write it yourself, copying the data from the input stream returned by the run-program .

+3
source

You are specifically asking about clisp. I will add that if you use Clozure CL, you can also easily execute os subprocesses.

Some examples:

 ;;; Capture the output of the "uname" program in a lisp string-stream ;;; and return the generated string (which will contain a trailing ;;; newline.) ? (with-output-to-string (stream) (run-program "uname" '("-r") :output stream)) ;;; Write a string to *STANDARD-OUTPUT*, the hard way. ? (run-program "cat" () :input (make-string-input-stream "hello") :output t) ;;; Find out that "ls" doesn't expand wildcards. ? (run-program "ls" '("*.lisp") :output t) ;;; Let the shell expand wildcards. ? (run-program "sh" '("-c" "ls *.lisp") :output t) 

Do a search to run the program in the CCL documents located here: http://ccl.clozure.com/ccl-documentation.html

There are a couple of nice Lisp ways to do this in this stackoverflow answer: Making a system call that returns stdout output as a string Once again, Rainer helps. Thanks Ranya.

+1
source

It is shorter

 (defun system(cmd) (ext:shell (string cmd))) > (system '"cd ..; ls -lrt; pwd") 
0
source

Source: https://habr.com/ru/post/1312501/


All Articles