我在字符串中收到一个脚本,试图找到一种使用python的子进程模块执行它的方法。 e.g。
import subprocess
script = """#!/usr/bin/python
print "inside script"
"""
subprocess.Popen(script)
这引发了一个OSError:说没有这样的文件或目录,这是公平的,因为我认为它试图寻找命令名。
然后我尝试subprocess.Popen(script, shell=True)
仅适用于shell命令并完全忽略#!在脚本的顶部。有没有办法让suprocess运行我的脚本存储在字符串中,就像它的可执行文件一样?
答案 0 :(得分:2)
正如您可以在Popen Python Documentation中读到Popen
的参数是要启动的可执行文件,而不是要执行的某些脚本的内容。您不能以这种方式使用Popen
。
如果您真的想要,可以将脚本写入文件,然后将该文件名传递给Popen,但对于您遇到的任何问题,这似乎都不是一个优雅的解决方案。
看到你想要的只是从字符串中执行一些Python代码,你将要使用exec builtin function
答案 1 :(得分:2)
此解决方案基于-c
(编译)Python解释器cmdline参数。它完全忽略了使用shell属性。
Popen可能以类似的方式创建。 subprocess.call
用于表示脚本实际上已执行,并且python解释器返回代码由执行的代码更改。
import subprocess
executable_code = """
print 'inside script'
print 123
"""
code_with_exception = """
raise Exception()
"""
ok_rc = subprocess.call(['python', '-c', executable_code])
assert ok_rc == 0
bad_rc = subprocess.call(['python', '-c', code_with_exception])
assert bad_rc == 1
其他改进是跳过'python'硬编码字符串并使用sys.executable
。
一个字符串,给出Python解释器的可执行二进制文件的绝对路径,在有意义的系统上。如果Python是 无法检索其可执行文件的真实路径,sys.executable 将是一个空字符串或无。
import sys
import subprocesss
code = "raise Exception()"
bad_rc = subprocess.call([sys.executable, '-c', code])
assert bad_rc == 1
答案 2 :(得分:1)
您可以通过将脚本转换为子python的stdin
来运行脚本。这可能是较大脚本的首选解决方案:
import sys
import subprocess as subp
import shutil
script = """\
import sys
print "hello", sys.argv
"""
p = subp.Popen([sys.executable, '-', 'arg1', 'arg2'], stdin=subp.PIPE)
p.stdin.write(script)
p.stdin.close()
p.wait()
我在ssh
个连接中使用此技巧来控制远程服务器。
答案 3 :(得分:1)
使用subprocess
模块执行字符串作为Python脚本:
>>> import subprocess, sys, textwrap
>>> subprocess.call(textwrap.dedent('''
... print "Hello, world!"
... '''), shell=True, executable=sys.executable)
Hello, world!
0
虽然@wich suggested为Python builtin function exec()
,但您可以使用multiprocessing
- 它是关于Python 2的声明:
>>> exec 'print "Hello, exec!"'
Hello, exec!
如果您想在其他流程中运行Python代码,可以使用concurrent.futures
modules或Hibernate Communications Link Failure in Hibernate Based Java Servlet application powered by MySQL:
#!/urs/bin/env python2
from multiprocessing import Process, freeze_support
def run(code):
exec code # Python 2
if __name__ == "__main__":
freeze_support()
Process(target=run, args=['print "Hello, multiprocessing"']).start()