问题
I've got a very large Lisp project whose output I'd like to programmatically pipe to a Python program, i.e. use Python to call the Lisp program on some input and get the output back into Python.
The project only compiles in Clozure Common Lisp (ccl64) and I did try to find a way to turn it into an executable (I'm using Mac OS X), but that ran into a lot of dead ends (I am not a Lisp programmer).
This documentation for Clozure Common Lisp should provide the solution to the above, but I was not able to understand it. The examples I made created a file, but Terminal would not run them as executables.
How to create executable for ccl64
I tried to follow this question's answer Compiling Common Lisp to an executable except using ccl64's save application function.
$ ccl64
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk (DarwinX8664)!
? (in-package :ccl)
#<Package "CCL">
? (defun main () (print "hello"))
MAIN
? (save-application "hello" :toplevel-function #'main)
I am trying to use Python's subprocess to invoke ccl64, run the Lisp program, and get the output. However, subprocess for some reason refuses to run the ccl64 command. Here is what I wrote so far:
import subprocess
process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
out, err = process.communicate()
The variable out
should contain the output of getting the usage/help from ccl64. Instead I get an error:
Traceback (most recent call last):
File "sub.py", line 3, in <module>
process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
How can I get Python to invoke ccl64 and get output from the Lisp project?
回答1:
The error in your Python code is clear: No such file or directory.
You need to tell in your Python code which application you want to run in a way that it actually finds it.
It's also not clear why you save a Lisp executable somewhere named hello
, but you are not trying to call it. With the necessary path. Your code tries to call Clozure CL - without the necessary path - but why? You just saved an executable. Why would you call Clozure CL to run it? I would also save the executable with prepending the kernel - that makes it self-contained.
Example:
Calling Clozure CL:
rjmba:~ joswig$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk (DarwinX8664)!
Defining the main
function:
? (defun main () (print "hello"))
MAIN
Saving an executable:
? (save-application "hello" :toplevel-function #'main :prepend-kernel t)
Running the new executable from the same directory:
rjmba:~ joswig$ ./hello
"hello"
Calling a Clozure CL application with an argument:
bash-3.2$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk (DarwinX8664)!
The function ccl::command-line-arguments
returns the arguments as a list. The first item is the called application itself.
? (defun main ()
(print (second (ccl::command-line-arguments))))
MAIN
? (save-application "hello"
:toplevel-function #'main
:prepend-kernel t)
Calling it:
bash-3.2$ ./hello hello!
"hello!"
来源:https://stackoverflow.com/questions/27221781/how-to-get-output-of-a-lisp-program-into-python