Выполнение команды оболочки из Common Lisp - PullRequest
23 голосов
/ 20 мая 2011

Как я могу выполнить команду оболочки (bash) в программе Common Lisp и назначить вывод переменной?

Ответы [ 8 ]

12 голосов
/ 20 мая 2011

ASDF обеспечивает RUN-SHELL-COMMAND, который работает со многими реализациями Common Lisp , включая ABCL, Allegro CL, CLISP, Clozure CL, ECL, GCL, LispWorks, SBCL, CMU, XCLи SCL.

Он принимает управляющую строку и список аргументов, например FORMAT, и синхронно выполняет результат, используя Bourne-совместимую оболочку.Захватить вывод, связав дополнительный поток.

11 голосов
/ 30 мая 2013

ITA выпустила подчиненную оболочку в рамках своего зонтичного проекта QITAB.

Некоторые ссылки, представляющие интерес:

Хранилище git в настоящее время размещено на common-lisp.net:

git clone git://common-lisp.net/projects/qitab/inferior-shell.git
8 голосов
/ 20 мая 2011

Вы можете использовать Trivial-shell ( url )

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

команда оболочки возвращает результат, поэтому вы можете присвоить его переменной.

В asdf.lisp файле вы можете прочитать:

;;;;Вероятно, нам следует перенести эту функциональность в собственную систему и отказаться от

;;;;использование его из пакета asdf.Тем не менее, это сломало бы неопределенное

;;;;существующее программное обеспечение, поэтому пока не существует четкой альтернативы, мы не можем осудить

;;;;это, и даже после того, как это устарело, мы будем поддерживать его в течение нескольких

;;;;лет, так что у всех есть время, чтобы уйти от этого.- тариф 2009-12-01

5 голосов
/ 13 апреля 2016

В настоящее время я бы использовал uiop:run-program, где uiop означает «универсальный ввод-вывод» и представляет собой слой совместимости, предоставляемый asdf3, ранее известный как asdf/driver.Как уже было сказано, asdf:run-shell-command устарел, и uiop наследует многие функции других библиотек, таких как trivial-shell.

readme UIOP

5 голосов
/ 30 мая 2013

Некоторые реализации CL имеют встроенные функции для этой цели. Например, SBCL имеет sb-ext:run-program, а CCL имеет run-program.

4 голосов
/ 02 октября 2016

В sbcl:

(sb-ext:run-program "/bin/sh" (list "-c" "whoami") :input nil :output *standard-output*)

У меня отлично работает :)

2 голосов
/ 30 мая 2015

Эта (appupdate.cl) программа является примером создания и выполнения сценария оболочки с использованием реализации Steel Bank Common Lisp (sbcl), которая предполагает, что у вас установлен sbcl и он находится на вашем пути.

Я написал это в Ubuntu 14.04 как простой способ автоматизировать обновление, обновление и обновление ядра приложения / системного программного обеспечения.

#!/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*)

Так что, конечно, он создает скрипт оболочки с именем update.sh, который направляется в / bin / bash через shebang (#!). После этого встроенная sb-ext: run-program направляет оболочку для выполнения / bin / chmod, передавая флаг "+ x" в качестве аргумента и / path / to / the-file. Эта функция изменяет режим доступа файла к исполняемому файлу (меняет разрешения).

Затем оболочка открыта и выполняет / bin / bash, а двоичному файлу bash передается аргумент местоположения файла исполняемых сценариев оболочки.

Наконец, файл удаляется из рабочего каталога (обратите внимание, что в этом случае appupdate.cl находится в моем домашнем каталоге, поэтому это рабочий каталог).

Файл appupdate.cl может быть выполнен из командной строки после его изменения на исполняемый файл и получения привилегий временного root:

:~$ chmod +x appupdate.cl

:~$ sudo bash

:~# ./appupdate.cl

:~# exit

Достаточно легко можно добавить команду sudo в скрипт (например, sudo apt-get update), и использование последовательности sudo bash не потребуется.

ПРИМЕЧАНИЕ. В LispWorks ide 14.04 (sys: run-shell-command "") по-прежнему применимо, даже если оно в некотором роде стало "устаревшей" функцией.

1 голос
/ 13 октября 2018

Я попробовал некоторые ответы, но это было не так просто. Вот что сработало легко:

(ql:quickload "external-program")
;; run shell command e.g. "ls -l" and capture the output into string *output*
(defparameter *output* 
              (with-output-to-string (out) 
                (external-program:run "ls" '("-l")  ; command with parameters as list of strings
                                      :output out)))
;; and after that, you can write functions to parse the output ...

Это из книги Эди Вейц Common Lisp Recipes, которая, на мой взгляд, принадлежит к полке любого серьезного программиста на Лиспе ...

...