如何使用 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)
,它仅适用于 shell 命令并且完全忽略了 #!在脚本的顶部。有没有办法让 suprocess 运行 我的脚本像可执行文件一样存储在字符串中?
正如您在 Popen Python Documentation 中看到的那样,Popen
的参数是要启动的可执行文件,而不是要执行的某些脚本的内容。您不能以这种方式使用 Popen
。
如果您真的想要,您可以将脚本写入一个文件,然后将该文件名传递给 Popen,但这似乎不是解决您的问题的完美方法。
既然你想要的只是从字符串中执行一些 Python 代码,你会想要使用 exec builtin function
此解决方案基于 -c
(编译)Python 解释器 cmdline 参数。它完全忽略使用 shell 属性。
Popen 可以用类似的方式创建。 subprocess.call
用于显示脚本实际上已执行,python 解释器 return 代码被执行的代码更改。
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
.
A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is
unable to retrieve the real path to its executable, sys.executable
will be an empty string or None.
import sys
import subprocesss
code = "raise Exception()"
bad_rc = subprocess.call([sys.executable, '-c', code])
assert bad_rc == 1
您可以 运行 将脚本放入 child 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
尽管如 you could use Python builtin function exec()
-- 它是关于 Python 2 的声明:
>>> exec 'print "Hello, exec!"'
Hello, exec!
如果你想 运行 Python 在不同的进程中编码,你可以使用 multiprocessing
or concurrent.futures
modules:
#!/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()
我收到一个字符串中的脚本,并试图找到一种使用 python 的子进程模块执行它的方法。例如
import subprocess
script = """#!/usr/bin/python
print "inside script"
"""
subprocess.Popen(script)
这会抛出一个 OSError:说没有这样的文件或目录,这很公平,因为我认为它正在尝试寻找命令名称。
然后我尝试了 subprocess.Popen(script, shell=True)
,它仅适用于 shell 命令并且完全忽略了 #!在脚本的顶部。有没有办法让 suprocess 运行 我的脚本像可执行文件一样存储在字符串中?
正如您在 Popen Python Documentation 中看到的那样,Popen
的参数是要启动的可执行文件,而不是要执行的某些脚本的内容。您不能以这种方式使用 Popen
。
如果您真的想要,您可以将脚本写入一个文件,然后将该文件名传递给 Popen,但这似乎不是解决您的问题的完美方法。
既然你想要的只是从字符串中执行一些 Python 代码,你会想要使用 exec builtin function
此解决方案基于 -c
(编译)Python 解释器 cmdline 参数。它完全忽略使用 shell 属性。
Popen 可以用类似的方式创建。 subprocess.call
用于显示脚本实际上已执行,python 解释器 return 代码被执行的代码更改。
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
.
A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None.
import sys
import subprocesss
code = "raise Exception()"
bad_rc = subprocess.call([sys.executable, '-c', code])
assert bad_rc == 1
您可以 运行 将脚本放入 child 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
尽管如 exec()
-- 它是关于 Python 2 的声明:
>>> exec 'print "Hello, exec!"'
Hello, exec!
如果你想 运行 Python 在不同的进程中编码,你可以使用 multiprocessing
or concurrent.futures
modules:
#!/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()