在python命令行上输入python命令
这篇文章的标题可能令人困惑,但基本上我希望能够做到以下几点:在python命令行上输入python命令,python,subprocess,Python,Subprocess,这篇文章的标题可能令人困惑,但基本上我希望能够做到以下几点: import subprocess subprocess.call(["python"]) subprocess.call(["import", "antigravity"]) subprocess.check_call(["print","\"This is so meta\" "]) subprocess.call(["exit()"]) 预期的行为是,它将打开一个python终端会话,然后打开xkcd comic 353,在
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脚本中运行其中的命令。我还希望能够检查脚本中运行的命令的输出。这可能吗?如果是,我需要使用什么库?子进程会这样做吗?类似这样的事情
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读取响应(通常会打印到屏幕上)您也可以使用:
如果出于某种原因希望在子流程中运行此操作,则可以使用:
要将标准输出重定向到变量,请执行以下操作:
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
请注意,控制台的sys.stdout
已重定向到MyStream(sys.stdout)
。它不打印任何内容,但将最后一个字符串存储在self.value
中。要打印到字符串,可以使用sys.\uu stdout\uuu.write
(注意下划线)
如果您需要与流程通信,您应该使用communicate()
方法,而不是stdin.write()
,否则您会发现一些不理想的效果
警告:请使用communicate()而不是.stdin.write、.stdout.read或.stderr.read,以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁
资料来源:
那么,看起来您想要自己的python命令?我说的对吗?是的,我希望能够用python调用我自己的命令。从一个单独的python脚本。您希望您的python脚本在哪里以及如何运行??我希望运行的python脚本将是上面列出的命令。我希望能够在“python命令行”中运行和实现类似于我在问题中编写的python脚本中的命令!我很高兴,很高兴我能帮助解决这个问题@J.F.Sebastian嗯。。。A) OP询问的是没有缓冲问题的输入,B)关于这个问题的其他答案有不同的方法-所以我不完全确定你建议我应该做什么?把我的改成模仿别人的回答?似乎有点像偷点…@Basic:a)如果您认为OPs输入已修复,请使用thencommunicate()
“怎么做”:突出显示解决方案中可能存在的问题。一个简单的警告就足够了。对于.communicate()
,只需+1即可。如果输入不依赖于输出,这是合适的。顺便说一句,您不需要调用e.wait()
.communicate()
已经在等待进程完成,即e.returncode返回后不是None
。为了便于阅读,您可以使用子流程导入Popen、PIPE、STDOUT中的,并使用三重引号在多行上输入命令,而不是\n
。此外,围绕单个参数的shell=False
和[]
是多余的。@J.F.Sebastion:如果输入确实依赖于输出,该怎么办?@DerekHalden:那么。communicate()
是不合适的。您可能有可能导致死锁的缓冲问题。看看你会用什么来代替?@DerekHalden:一般来说,pexpect
module。在您的特定情况下,我会首先尝试一下,有没有办法使用它将输出重定向到代码中的变量?
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
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)