curl不被识别,使用Popen()

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) 

这是我现在使用的代码,我得到的错误,curl无法识别。 当我在solrData.json文件所在的相同目录中运行命令时:

 curl "http://localhost:8983/solr/update/json?commit=true" --data-binary @solrData.json -H "Content-type:application/json" 

它运行完美。 curl是在系统path中,并在那里作用。 另外作为比较,这工作得很好:

 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()) 

这是可行的解决scheme。 谢谢zmo和Martijn Pieters的帮助。

你正在传递一个参数列表 ,但是设置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'}) 

来自Popen manpage :

在shell = True的Unix上,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) 

但是你为什么要使用pycurl来使用curl,而你有pycurl库,这使得它更容易使用curl? 这是一个受文件上传示例启发的代码:

 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