2010-06-10 24 views
4

Je suis en train de créer une commande « système » pour clisp qui fonctionne comme cecommandes shell en cours d'exécution avec gnu clisp

(setq result (system "pwd")) 

;;now result is equal to /my/path/here 

J'ai quelque chose comme ceci:

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

Mais, je suis pas sûr de savoir comment transformer un flux en chaîne. J'ai examiné l'hyperspec et google plus de quelques fois.

edit: travailler avec la commande de Ranier et en utilisant avec sortie à flux,

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

Et puis essayer de courir grep, qui est sur mon chemin ...

[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 

Répondre

5

Quelque chose comme ça?

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 
..." 
+0

question: qu'est-ce que l': sortie indique? est-ce une syntaxe de paramètre nommé? –

+0

En outre, votre suggestion ne fonctionne pas, j'ai ajouté info ci-dessus –

+0

: sortie est un paramètre qui définit où la sortie sera dirigée vers. dans ce cas, il sera dirigé vers un flux. –

3

par le CLISP documentation on run-program, l'argument :output devrait être l'un des

  • :terminal - écrit dans le terminal
  • :stream - crée et renvoie une entrée flux à partir de laquelle vous pouvez lire
  • un désignateur chemin - écrit dans le fichier désigné
  • nil - ignore la sortie

Si vous cherchez à récupérer la sortie dans une chaîne, vous devrez utiliser un en lecture écrire une boucle de copie pour transférer les données du flux renvoyé vers une chaîne. Vous avez déjà with-output-to-string en jeu, selon la suggestion de Rainer, mais au lieu de fournir ce flux de sortie à run-program, vous devrez écrire vous-même, en copiant les données du flux d'entrée retourné par run-program.

1

Vous vous interrogez spécifiquement sur les clivages. Je vais ajouter ici que si vous utilisez Clozure CL, vous pouvez également exécuter facilement des sous-processus os.

Quelques exemples:

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

Effectuer une recherche d'exécution programme dans la documentation du CCA situé ici: http://ccl.clozure.com/ccl-documentation.html

Il y a quelques belles façons Lisp de le faire dans cette réponse stackoverflow: Making a system call that returns the stdout output as a string Une fois encore une fois, Rainer à la rescousse. Merci Ranier.

0

Ceci est un plus court

(defun system(cmd) 
    (ext:shell (string cmd))) 

> (system '"cd ..; ls -lrt; pwd")