CLISP ext:изпълни програма

Имам проблем с използването на run-program с аргументи. Документацията на http://www.clisp.org/impnotes/shell.html е много непълно за начинаещ като мен и ще трябва да видя някои примери.

По-специално, как мога да получа списъка с директории с файлове с разширение "txt"?

Това работи:

(ext:run-program "ls" ) ; I am running on Mac OS X

но ако добавя аргументи, не става. Опитах:

(ext:run-program "ls" :arguments "*.txt")
(ext:run-program "ls" :arguments '(*.txt))
(ext:run-program "ls *.txt)

Може ли някой да ми каже правилния синтаксис и, надявам се, да предостави още няколко примера за run-program?

Имайте предвид, че горното е само пример. Това, което искам, е да мога да използвам run-command, а не да изброявам директорията, което мога да направя с list-directory.

Благодаря за всяка помощ.


person Leo    schedule 19.11.2014    source източник


Отговори (2)


Списък с файлове

Първо, ако всичко, което искате, е да изброявате файлове, можете да използвате стандартния directory или специфични за CLISP ext:dir.

Глобиране

Второ, "*" globbing се разширява от shell, а не от отделни команди, така че трябва да използвате ext:run-shell-command вместо ext:run-program:

> (ext:run-shell-command "ls *.txt")
foo.txt

> (ext:run-program "ls" :arguments '("foo.txt"))
foo.txt

> (ext:run-program "ls")
foo.txt
bar.c

Резюме

Ръководството предполага известно ниво на познаване на начина, по който съвременните операционни системи работят в това отношение. Другият отличен отговор разглежда тези въпроси в детайли; накратко:

  • run-program изпълнява друга програма, използвайки стандартната парадигма fork/exec
  • run-shell-command минава през shell, така че можете да използвате globbing и неща като цикли
  • shell е предимно за интерактивна употреба

Още примери

Можете да намерите повече примери за run-program в CLISP теста пакет.

Ако искате да четете от компресиран файл, можете да направите това:

;; return lines as a list
(with-input-from-file (in (ext:make-pipe-input-stream "gunzip -c myfile.gz"))
  (loop for l = (read-line in nil nil)
    while l
    collect l))

Всъщност можете да използвате CLISP като своя обвивка!

person sds    schedule 19.11.2014
comment
Много благодаря! Това работи. Знаете ли къде мога да намеря по-подробно описание на run-program, run-shell-command и shell, с примери? Кога да използвате кое? TIA - person Leo; 20.11.2014
comment
yw. не доколкото знам. нека превърнем този въпрос в един: какво искате да правите? - person sds; 20.11.2014
comment
Искам да науча как да взаимодействам с други приложения, да изпълнявам програми и да обменям данни между тях и CLISP. Един пример, който сега имам в ръцете си, е как да разархивирам файл, да изчакам да бъде декомпресиран и да го прочета. Мисля, че обясненията, които ми дадохте, са много полезни, но малко прекалено сложни за начинаещ като мен, така че може би подробна документация би била много полезна за много хора. - person Leo; 20.11.2014

Опитайте нещо подобно

(ext:run-program "stat" :arguments '("/tmp" "/sys"))

Използвам stat, а не ls в този пример.

Това, което може да искате, е глобиране (прочетете glob(7)). Трябва да го направите сами в Lisp или да стартирате /bin/sh -c; с други думи, от вас зависи да създадете разширения списък, подаден след :arguments. (Не можете да подадете *.txt като единичен аргумент, това ще има същия ефект като цитиран аргумент на обвивката, както в командата на обвивката
ls '*.txt')

Това не е специфично за CLISP. ext:run-program вероятно разклонява, след което извиква (в дъщерния) execve(2), така че трябва да направите сами глобирането.

Може би искате CLISP еквивалент на glob(3) или fnmatch(3). Не знам достатъчно CLISP дали ги има или не.

Прочетете Разширено Linux програмиране, за да получите по-ясна представа за това. В POSIX системи процесът на извикване (често вашата обвивка, когато въвеждате команда, или вашата програма Common Lisp, ако използвайки ext:run-program ....) трябва да разшири и изгради списъка с аргументи. Въпросът е, че когато стартирате ls *.txt, вашата обвивка (а не процесът ls) разширява *.txt, така че ls получава разширен списък с аргументи, като напр. a.txt foo.txt bar.txt; така че трябва да направите същото във вашия Lisp код.

person Basile Starynkevitch    schedule 19.11.2014