在python命令行输入python命令

Posted

技术标签:

【中文标题】在python命令行输入python命令【英文标题】:Input python commands on the python command line 【发布时间】:2014-04-20 18:58:36 【问题描述】:

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

import subprocess

subprocess.call(["python"])
subprocess.call(["import", "antigravity"])
subprocess.check_call(["print","\"This is so meta\" "])
subprocess.call(["exit()"])

预期的行为是它会打开一个 python 终端会话,然后打开 xkcd comic 353,在命令行中打印 'this is so meta',最后退出 python 命令行。

基本上,我希望能够打开一个 python 会话,并从我的 python 脚本中运行命令。我还希望能够检查我在脚本中运行的命令的输出。这可能吗?如果是这样,我需要使用什么库?子进程会这样做吗?

【问题讨论】:

那么,看起来你想要你自己的python命令?我说的对吗? 是的,我希望能够在 python 中调用我自己的命令。来自一个单独的 python 脚本。 你想要你的 python 脚本的位置和方式?? 我要运行的 python 脚本将是上面列出的命令。我希望能够运行并在“python 命令行”中执行命令,就像我在问题中写的那样。 看这个:***.com/questions/22131980/… 【参考方案1】:

这样的……

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

所以我们正在创建一个进程并告诉它输入将来​​自标准输入(就像有人打字一样)。然后我们写任何我们喜欢的东西并从标准输出读取响应(通常会打印到屏幕上)

【讨论】:

非常感谢,这正是我所需要的! 很高兴,很高兴我能帮上忙 这个解决方案受到buffering issue的影响 @JFSebastian Well... A) OP 询问 没有 有缓冲问题的输入,B) 关于这个问题还有其他答案不同的方法 - 所以我不完全确定你建议我应该做什么?改变我的模仿别人的答案?似乎有点像偷点... @Basic: A) 如果您认为 OP 输入已修复,请使用 communicate() B) “做什么”:突出显示解决方案中可能存在的问题。一个简单的警告the link 就足够了。【参考方案2】:

如果你需要与进程通信,你应该使用communicate()方法而不是stdin.write(),否则你会发现一些不理想的效果。

警告使用communicate() 而不是.stdin.write、.stdout.read 或.stderr.read 以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致的死锁。

来源: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)

【讨论】:

+1 表示.communicate()。如果输入不依赖于输出是合适的。顺便说一句,你不需要打电话给e.wait().communicate() 已经在等待进程完成,即,e.returncode is not None 在它返回之后。为了便于阅读,您可以使用from subprocess import Popen, PIPE, STDOUT 并使用三引号代替\n 在多行上输入命令。此外,围绕单个参数的shell=False[] 是多余的。 @J.F. Sebastion:如果输入确实依赖于输出怎么办? @DerekHalden:那么.communicate() 不合适。而且您可能会遇到可能导致死锁的缓冲问题。见Q: Why not just use a pipe (popen())? 你会用什么代替? @DerekHalden:一般来说,pexpect 模块。在您的特定情况下,我会先尝试@unutbu's answer【参考方案3】:

您也可以使用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()

将标准输出重定向到变量:

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

请注意,consolesys.stdout 已重定向到 MyStream(sys.stdout)。它不打印任何内容,但将最后一个字符串存储在self.value 中。要打印到字符串,您可以使用sys.__stdout__.write(注意下划线)。


【讨论】:

有没有办法使用它来将输出重定向到我的代码中的变量?

以上是关于在python命令行输入python命令的主要内容,如果未能解决你的问题,请参考以下文章

Openwrt如何输入命令行?

在python交互命令行中如何清屏

python命令行补全

python开发命令行脚本

如何在命令行里运行python脚本

python项目输出到sys和命令行中的不一样