繁体   English   中英

如何使用python子进程模块执行包含脚本的字符串

[英]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代码,则可以使用multiprocessingconcurrent.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM