Ну, так как это зависит от системы, есть много языков, которые не имеют встроенной оболочки для различных необходимых системных вызовов.
Например, сам Common Lisp не предназначен для работы в какой-либо конкретной системе. SBCL (реализация Common Lisp для Steel Banks), тем не менее, обеспечивает расширение для Unix-подобных систем, как и большинство других реализаций CL. Конечно, это гораздо более «мощно», чем просто получение выходных данных (вы можете контролировать процесс выполнения, можете задавать все виды направлений потока и т. Д., См. Руководство SBCL, глава 6.3), но это легко напишите небольшой макрос для этой конкретной цели:
(defmacro with-input-from-command ((stream-name command args) &body body)
"Binds the output stream of command to stream-name, then executes the body
in an implicit progn."
`(with-open-stream
(,stream-name
(sb-ext:process-output (sb-ext:run-program ,command
,args
:search t
:output :stream)))
,@body))
Теперь вы можете использовать его так:
(with-input-from-command (ls "ls" '("-l"))
;;do fancy stuff with the ls stream
)
Возможно, вы хотите, чтобы все это втиралось в одну строку. Макрос тривиален (хотя возможно более краткий код):
(defmacro syslurp (command args)
"Returns the output from command as a string. command is to be supplied
as string, args as a list of strings."
(let ((istream (gensym))
(ostream (gensym))
(line (gensym)))
`(with-input-from-command (,istream ,command ,args)
(with-output-to-string (,ostream)
(loop (let ((,line (read-line ,istream nil)))
(when (null ,line) (return))
(write-line ,line ,ostream)))))))
Теперь вы можете получить строку с этим вызовом:
(syslurp "ls" '("-l"))