这个标题可能令人困惑,但基本上我希望能够做到以下几点:
import subprocess
subprocess.call(["python"])
subprocess.call(["import", "antigravity"])
subprocess.check_call(["print","\"This is so meta\" "])
subprocess.call(["exit()"])
预期的行为是它将打开一个python终端会话,然后打开xkcd漫画353,打印'这是如此元'到命令行,最后退出python命令行。
基本上,我希望能够打开python会话,并从我的python脚本中运行命令。我还希望能够检查我在脚本中运行的命令的输出。这可能吗?如果是这样,我需要使用哪个库?子进程会这样做吗?
答案 0 :(得分:2)
像这样......
import subprocess
proc = subprocess.Popen(
'python',stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
proc.stdin.write('import antigravity\n')
proc.stdin.write('print "something"\n')
proc.stdin.close()
result = proc.stdout.read()
print result
所以我们正在创建一个进程并告诉它输入将来自stdin(就像有人打字一样)。然后我们编写任何我们喜欢的内容并从stdout读取响应(通常会打印到屏幕上)
答案 1 :(得分:2)
您也可以使用code module:
import code
console = code.InteractiveConsole()
console.push('import antigravity')
console.push('print "something"')
如果由于某种原因你希望在子流程中运行它,那么你可以使用multiprocessing module:
import code
import multiprocessing as mp
def work():
console = code.InteractiveConsole()
console.push('import antigravity')
console.push('print "something"')
if __name__ == '__main__':
proc = mp.Process(target=work)
proc.start()
proc.join()
将stdout重定向到变量:
import code
import sys
class MyStream(object):
def __init__(self, target):
self.target = target
self.value = None
def write(self, s):
if s.strip():
self.value = s
sys.stdout = stream = MyStream(sys.stdout)
console = code.InteractiveConsole(locals=locals())
console.push('import antigravity')
console.push('print "something"')
sys.__stdout__.write('output: {}\n'.format(stream.value))
打印
output: something
请注意,console
的{{1}}已重定向到sys.stdout
。它不打印任何内容,但将最后一个字符串存储在MyStream(sys.stdout)
中。要打印到字符串,您可以使用self.value
(注意下划线)。
答案 2 :(得分:2)
如果您需要与流程进行通信,则应使用communicate()
方法代替stdin.write()
,否则您可能会发现一些不合适的效果。
警告使用communic()而不是.stdin.write,.stdout.read或.stderr.read来避免因任何其他OS管道缓冲区填满和阻止子进程而导致的死锁。
来源:http://docs.python.org/2/library/subprocess.html#popen-objects
from subprocess import PIPE, STDOUT, Popen
e = Popen(["/usr/local/bin/python3"], stdout = PIPE, stdin = PIPE, stderr = STDOUT, shell = False)
out, err = e.communicate(b"""
import sys
print('Interactive python version: %s' % str(sys.version))
sys.exit(4)
""")
e.wait()
print ('Exit code', e.returncode)
print ('Output', out)