[英]How to execute a string containing a script using python subprocess module
我收到一个字符串脚本,并试图找到一种使用python的子进程模块执行该脚本的方法。 例如
import subprocess
script = """#!/usr/bin/python
print "inside script"
"""
subprocess.Popen(script)
这引发OSError:说没有这样的文件或目录,这很公平,因为我认为它试图查找命令名。
然后subprocess.Popen(script, shell=True)
我尝试了subprocess.Popen(script, shell=True)
,它仅适用于shell命令,完全忽略了#! 在脚本的顶部。 有什么办法可以让suprocess运行以字符串形式存储的脚本(例如其可执行文件)?
正如你在读POPEN Python文档的参数Popen
是一个可执行文件来启动,而不是一些脚本的内容来执行。 您不能以这种方式使用Popen
。
如果确实需要,可以将脚本写入文件,然后将该文件名传递给Popen,但这对于您遇到的任何问题似乎都不是一个很好的解决方案。
看起来您只需要从字符串中执行一些Python代码,就可以使用exec内置函数
此解决方案基于-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
您可以通过将脚本泵入子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
连接中使用此技巧来控制远程服务器。
要使用subprocess
模块将字符串作为Python脚本执行:
>>> import subprocess, sys, textwrap
>>> subprocess.call(textwrap.dedent('''
... print "Hello, world!"
... '''), shell=True, executable=sys.executable)
Hello, world!
0
尽管正如@wich所建议的那样,您可以使用Python内置函数exec()
-这是关于Python 2的声明:
>>> exec 'print "Hello, exec!"'
Hello, exec!
如果要在其他过程中运行Python代码,则可以使用multiprocessing
或concurrent.futures
模块 :
#!/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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.