Exécution d'une commande shell à partir de Common Lisp

Comment puis-je exécuter une commande shell (bash) dans un programme Lisp commun et affecter la sortie à une variable?

21
demandé sur Terje Norderhaug 2011-05-20 02:16:25

7 réponses

ASDF offre RUN-SHELL-COMMAND qui fonctionne avec beaucoup de Common Lisp implémentations y compris ABCL, Allegro CL, CLISP, Clozure CL, ECL, GCL, LispWorks, SBCL, CMU, XCL et SCL.

Il faut une chaîne de contrôle et une liste d'arguments comme FORMAT, et exécute le résultat de façon synchrone en utilisant un shell compatible Bourne. Capturez la sortie en liant un flux optionnel.

12
répondu Terje Norderhaug 2011-05-20 00:09:55

ITA a publié inférieur-shell dans le cadre de leur projet qitab.

Quelques liens d'intérêt possibles :

un dépôt git est actuellement hébergé à common-lisp.net :

git clone git://common-lisp.net/projects/qitab/inferior-shell.git
11
répondu thodg 2013-05-30 05:21:17

Vous pouvez envisager d'utiliser des trivial-shell ( url)

(trivial-shell:shell-command "echo foo")

la commande shell renvoie la sortie, de sorte que vous pouvez l'assigner à une variable.

asdf.lisp le fichier, vous pouvez lire:

;;;; nous devrions probablement déplacer cette fonctionnalité vers son propre système et déprécier

;;;; utilisation de la faa paquet. Toutefois, cela ne serait pas spécifié

;;;; logiciels existants, donc, tant qu'une alternative claire n'existe pas, nous ne pouvons pas déprécier

;;;; il, et même après qu'il a été abandonné, nous allons le soutenir un peu

;;;; années pour que chacun ait le temps de s'en éloigner. -- tarif 2009-12-01

8
répondu Spec 2011-05-20 06:44:52

certaines implémentations de CL ont des fonctions intégrées à cet effet. Par exemple, SBCL a sb-ext:run-program, et CCL a run-program.

5
répondu Mars 2013-05-30 07:01:47

de nos jours j'utiliserais uiop:run-program, où uiop signifie "universal input output" et est une couche de compatibilité fournie par asdf3, anciennement connue sous le nom de asdf/driver. Comme il a été dit asdf:run-shell-command est obsolète et uiop hérite de nombreuses fonctionnalités d'autres bibliothèques comme trivial-shell.

UIOP readme

5
répondu Michael E. 2016-04-13 20:46:26

This (appupdate.cl) le programme est un exemple de création et d'exécution d'un script shell en utilisant L'implémentation de Steel Bank Common Lisp (sbcl), qui suppose que vous avez installé sbcl et ses dans votre chemin.

Je l'ai écrit sur Ubuntu 14.04 comme un moyen simple d'effectuer l'automatisation de la mise à jour, la mise à niveau, et la mise à niveau du noyau du logiciel de l'application/système.

#!/usr/local/bin/sbcl --script
(with-open-file (str "/home/geo/update.sh"
                     :direction :output
                     :if-exists :supersede
                     :if-does-not-exist :create)
  (format str "#! /bin/bash~%~%apt-get update~%~%apt-get upgrade -y~%~%apt-get dist-upgrade -y~%~%exit~%))
(sb-ext:run-program "/bin/chmod" '("+x" "/home/geo/update.sh")
    :output *standard-output*)
(sb-ext:run-program "/bin/bash" '("/home/geo/update.sh")
    :output *standard-output*)
(sb-ext:run-program "/bin/rm" '("-rf" "/home/geo/update.sh")
    :output *standard-output*)

donc bien sûr il crée un script shell intitulé update.sh, qui est dirigé vers / bin / bash via shebang (#!). Après cela, le programme SB-ext:run construit indique à un shell d'exécuter /bin /chmod en passant le drapeau "+x" comme argument et le fichier/path/to / the-file. Cette fonction change le mode d'accès du fichier exécutable (modifie les permissions).

ensuite, un shell est ouvert et exécute /bin/bash et le binaire bash passe l'argument de l'emplacement du fichier exécutable des scripts shell.

enfin le fichier est supprimé du répertoire de travail (noter dans ce cas l'applupdate.cl est dans mon répertoire personnel donc est le répertoire de travail).

l'application.le fichier cl peut être exécuté à partir de la ligne de commande après qu'il a été changé en exécutable et que des privilèges root temporaires ont été gagnés:

:~$ chmod +x appupdate.cl

:~$ sudo bash

:~# ./appupdate.cl

:~# exit

assez facilement la commande sudo pourrait être ajoutée au script (par exemple sudo apt-get update) et l'utilisation de la séquence sudo bash ne serait pas nécessaire.

NOTE: dans L'ide de LispWorks du 14.04 le (sys:run-shell-command "") est toujours applicable même si elle est en quelque sorte devenue une fonction "d'héritage".

2
répondu oOpSgEo 2015-05-29 21:23:55

dans sbcl:

(sb-ext:exécuter le programme/bin/sh" (liste "-c" "whoami") :entrée néant :sortie standard-sortie)

Cela fonctionne bien pour moi:)

2
répondu lisperl 2016-10-01 23:59:15