1
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 在系统路径中,一切正常。同样作为比较,这很好用:

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 的帮助。

4

2 回答 2

2

您正在传递参数列表,但是 set 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'})
于 2013-06-26T10:56:10.190 回答
0

来自Popen 手册页

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

但是为什么要使用 subprocess 来使用 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()

甚至比 using 更简单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

高温高压

于 2013-06-26T11:08:01.587 回答