p = Popen(["curl", "http://localhost:8983/solr/update/json?commit=true", "--data-binary", "@solrData.json", "-H", "Content-type:application/json"], cwd=r"C:/Users/SOLR/docs", shell=True)
这是我现在正在使用的代码,我得到卷曲无法识别的错误。 当我在solrData.json文件所在的同一目录中运行命令时:
curl "http://localhost:8983/solr/update/json?commit=true" --data-binary @solrData.json -H "Content-type:application/json"
它完美运行。卷曲在系统路径中,并且在那里工作。 另外作为比较,这很好用:
p = Popen("java -jar post.jar solrData.xml", cwd=r"C:/Users/SOLR/docs")
修改
import requests
# open the file to upload
with open('C:/Users/SOLR/docs/solrData.json', 'rb') as fin:
# execute the post request
headers = {'Content-type': 'application/json'}
r = requests.post("http://localhost:8983/solr/update/json", params=dict(commit="true"), headers=headers, data=fin.read())
这是有效的解决方案。谢谢zmo和Martijn Pieters的帮助。
答案 0 :(得分:2)
您正在传递参数的列表,但请设置shell=True
。关闭后者(删除参数,False
是默认值)并让Python处理命令:
p = Popen(["curl", "http://localhost:8983/solr/update/json?commit=true", "--data-binary", "@solrData.json", "-H", "Content-type:application/json"], cwd=r"C:/Users/SOLR/docs")
请注意,安装python-requests
库并从Python完成整个任务会非常简单:
import requests
with open('C:/Users/SOLR/docs/solrData.json', 'r') as solrdata:
r = requests.post('http://localhost:8983/solr/update/json?commit=true',
data=solrdata, headers={'Content-type': 'application/json'})
答案 1 :(得分:0)
在Unix上,shell = True,shell默认为/ bin / sh。如果args是一个字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下键入时完全相同。这包括,例如,引用或反斜杠转义带有空格的文件名。如果args是一个序列,则第一个项指定命令字符串,并且任何其他项将被视为shell本身的附加参数。也就是说,Popen相当于:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
在具有shell = True的Windows上,COMSPEC环境变量指定默认shell。您需要在Windows上指定shell = True的唯一时间是您希望执行的命令是否内置到shell中(例如dir或copy)。您不需要shell = True来运行批处理文件或基于控制台的可执行文件。
所以你需要发出以下命令:
p = Popen(["curl", "http://localhost:8983/solr/update/json?commit=true", "--data-binary", "@solrData.json", "-H", "Content-type:application/json"], cwd=r"C:/Users/SOLR/docs", shell=False)
但为什么要使用子进程来使用curl,而你有pycurl
库可以更容易地使用curl?这是受the file upload example启发的代码:
import os
import pycurl
import cStringIO
# here's a handler to expose the read_callback method
class FileReader:
def __init__(self, fp):
self.fp = fp
def read_callback(self, size):
return self.fp.read(size)
# here's a buffer to handle the output of the pycurl request
buf = cStringIO.StringIO()
# we open the file
with open('solrData.json', 'rb') as fin:
# get its size
filesize = os.path.getsize('solrData.json')
# initiates curl
c = pycurl.Curl()
# setup curl (url, as a post request, file upload size and content, content-type and output buffer)
c.setopt(c.URL, 'http://localhost:8983/solr/update/json?commit=true')
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.POSTFIELDSIZE, filesize)
c.setopt(pycurl.READFUNCTION, FileReader(f).read_callback)
c.setopt(pycurl.HTTPHEADER, ["Content-type: application/json"])
c.setopt(c.WRITEFUNCTION, buf.write)
# we execute the query
c.perform()
# and write the result of the query
with open('C:/Users/SOLR/docs/result.json') as f:
f.write(buf.getvalue())
# and finally we close the buffer
buf.close()
甚至比使用pycurl
更简单,您可以使用requests
库:
import requests
# open the file to upload
with open('solrData.json', 'rb') as fin:
# execute the post request
headers = {'Content-type': 'application/json'}
r = requests.post("http://httpbin.org/get", params=dict(commit=True), headers=headers, data=fin.read())
# write the result
with open('C:/Users/SOLR/docs') as f:
f.write(f.text) # write the json data in text file
print f.json() # print the json content as python datatypes
HTH