所以我试图在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 / parse',' - d','\'{“q”:“让我们说些什么”} \'', '|','python',' - m','json.tool'],'returncode':2,'stdout':b'','stderr':无}
如果我从命令行调用我的python程序,这是输出:
curl:选项-m:期望一个正确的数值参数curl:尝试'curl --help'或'curl --manual'获取更多信息{'args':['curl',' - X','POST',' localhost:5000 / parse',' - d','\'{“q”:“让我们说些什么”} \'','|','python',' - m','json.tool'], 'returncode':2,'stdout':b'','stderr':无}
我试着到处寻找但是不能让它继续下去。非常感谢一些帮助。
更新:我第一次误解了这个问题。匆匆阅读细节,所以我在那里道歉。您遇到问题是因为您尝试使用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问题还有很多关于这个主题的问题。