所以我试图在python中编写一个简单的包装器来调用rasa,这是一个nlu工具。我在命令行上写的命令是:
curl -X POST" localhost:5000 / parse" -d' {" q":"我正在寻找他妈的墨西哥食物"}' | python -m json.tool
我期望的输出是这样的:
%收到的总百分比%Xferd平均速度时间时间当前时间 Dload上载总左转速度 100 545 0 500 100 45 33615 3025 - : - : - - : - : - - : - : - 35714
加上json文件的外印。
我在python中编写了这个程序:
import subprocess
utterance = "Lets say something"
result = subprocess.run(["curl", "-X", "POST", "localhost:5000/parse", "-d", "'{\"q\":\""+utterance+"\"}'", "|", "python", "-m", "json.tool"], stdout=subprocess.PIPE)
print(vars(result))
print(result.stdout.decode('utf-8'))
不幸的是我的输出是这样的,这意味着我实际上并没有从curl调用返回:
{' args':[' curl',' -X',' POST',' localhost:5000 /解析',' -d',' \' {" q":"让我们说些什么"} \' ',' |',' python',' -m',' json.tool'],'返回码':2,' stdout':b'',' stderr':无}
如果我从命令行调用我的python程序,这就是输出:
curl:选项-m:期望一个合适的数字参数 卷曲:尝试卷曲 - 帮助'或者' curl --manual'欲获得更多信息 {' args':[' curl',' -X',' POST',' localhost:5000 / parse' ;,' -d',' \' {" q":"让我们说些什么"} \'' ;,' |',' python',' -m',' json.tool'],' returncode&#39 ;:2,' stdout':b'',' stderr':无}
我试着到处寻找但是不能让它继续下去。真的很感激一些帮助。
答案 0 :(得分:1)
更新:我第一次误解了这个问题。匆匆阅读细节,所以我在那里道歉。您遇到问题是因为您尝试使用Popen将两个命令组合在一起。然而,管道运算符是由shell实现的,而不是python。所以它期望你的命令只是一个与curl相关的命令。这很复杂,但你有选择。
我认为对于您的特定示例,最简单的是不要尝试将命令链接到json.tool。你实际上没有必要。你已经在python中了,所以你可以自己打印你自己卷曲的输出。使用python看起来像
import json
import shlex
from subprocess import Popen, PIPE
command = 'curl -XGET http://localhost:9200'
p = Popen(shlex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate()
if p.returncode != 0:
print(err)
j = json.loads(output.decode("utf-8"))
print(json.dumps(j, indent=4, sort_keys=True))
但是,如果你想要的长期实际上是用管道连接多个进程,那么它取决于场景。最简单的方法是将shell=True
传递给Popen
并传递确切的命令(不是参数列表)。这会将所有内容委托给shell。我需要警告你当命令基于用户输入时,这是非常可利用的。 2.x pipes.quote()
和3.x shlex.quote()
都建议如何转义命令,以便 安全。
from subprocess import Popen, PIPE
command = 'curl -XGET http://localhost:9200 | python -m json.tool'
p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
output, err = p.communicate()
if p.returncode != 0:
print(err)
print(output.decode("utf-8"))
因此,如果您发现自己需要连接流程但有基于用户输入的内容,则可以使用multiple processes并自行连接。
import shlex
from subprocess import Popen, PIPE
command1 = 'curl -XGET http://localhost:9200'
command2 = 'python -m json.tool'
p1 = Popen(shlex.split(command1), stdout=PIPE)
p2 = Popen(shlex.split(command2), stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()
output, err = p2.communicate()
if p2.returncode != 0:
print(err)
print(output.decode("utf-8"))
如果你好奇的话,This问题还有更多关于这个主题的问题。