Подтвердить что ты не робот

Выполнение команды оболочки из Common Lisp

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Некоторые ссылки возможного интереса:

A git репозиторий в настоящее время размещен в общем режиме lisp.net:

git clone git://common-lisp.net/projects/qitab/inferior-shell.git

Ответ 3

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

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

shell-command возвращает вывод, поэтому вы можете назначить его переменной.

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

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

;;;; использовать его из пакета asdf. Однако это нарушит неуказанный

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

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

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

Ответ 4

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

Ответ 5

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

UIOP readme

Ответ 6

В sbcl:

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

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

Ответ 7

Эта (appupdate.cl) программа является примером создания и выполнения оболочки script с использованием реализации 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*)

Итак, он создает оболочку script под названием update.sh, которая направлена ​​на/bin/bash через shebang (#!). После этого sb-ext: run-program built создает оболочку для выполнения /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 в script (например, обновление sudo apt-get) и использовать последовательность sudo bash не потребуется.

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

Ответ 8

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

(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 которая, на мой взгляд, принадлежит к полке любого серьезного программиста на Lispе...