Как я могу выполнить команду оболочки (bash) в общей программе Lisp и назначить вывод переменной?
Выполнение команды оболочки из Common Lisp
Ответ 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.
Некоторые ссылки возможного интереса:
- http://common-lisp.net/gitweb?p=projects/qitab/inferior-shell.git
- http://common-lisp.net/projects/qitab/
- http://cliki.net/inferior-shell
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
.
Ответ 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е...