在python命令行上输入python命令

时间:2014-03-15 10:46:14

标签: python subprocess

这个标题可能令人困惑,但基本上我希望能够做到以下几点:

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脚本中运行命令。我还希望能够检查我在脚本中运行的命令的输出。这可能吗?如果是这样,我需要使用哪个库?子进程会这样做吗?

3 个答案:

答案 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)