简体   繁体   English

想要通过python的子进程或pycurl运行curl命令

[英]Want to run a curl command either through python's subprocess or pycurl

I have the following command which adds a user to the administrator group of a gerrit instance, 我有以下命令,它将用户添加到gerrit实例的管理员组,

 curl -X POST -H "Content-Type:application/json;charset=UTF-8" -u nidhi:pswd http://host_ip:port/a/groups/Administrators/members.add -d '{"members":["user@example.com"]}'

When I run this command on my terminal, it runs perfectly and gives the expected output. 当我在终端上运行此命令时,它可以完美运行并提供预期的输出。

But, I want to execute this command in python either using the subprocess or pycurl library. 不过,我想无论是使用python中执行此命令subprocesspycurl库。

Using subprocess I wrote the following code, 使用subprocess我编写了以下代码,

def add_user_to_administrator(u_name,url):
    bashCommand = 'curl -X POST -H "Content-Type:application/json;charset=UTF-8" -u nidhi:pswd http://'+url+'/a/groups/Administrators/members.add -d '+"'"+'{"members":["$u_n@example.com"]}'+"'"
    bashCommand = string.Template(bashCommand).substitute({'u_n':u_name})
    print bashCommand.split()
    process = subprocess.Popen(bashCommand.split())

It shows no error but no changes are seen in the administrator group. 它没有显示错误,但是在管理员组中没有看到任何更改。

I tried the same using pycurl , 我用pycurl尝试了相同的方法,

def add_user_to_administrator2(u_name,url):
    pf = json.dumps({"members":[str(str(u_name)+"@example.com")]})
    headers = ['Content-Type:application/json;charset=UTF-8']
    pageContents = StringIO.StringIO()


    p = pycurl.Curl()
    p.setopt(pycurl.FOLLOWLOCATION, 1)
    p.setopt(pycurl.POST, 1)
    p.setopt(pycurl.HTTPHEADER, headers)
    p.setopt(pycurl.POSTFIELDS, pf)
    p.setopt(pycurl.WRITEFUNCTION, pageContents.write)
    p.setopt(pycurl.VERBOSE, True)
    p.setopt(pycurl.DEBUGFUNCTION, test)
    p.setopt(pycurl.USERPWD, "nidhi:pswd")
    pass_url=str("http://"+url+"/a/groups/Administrators/Administrators/members.add").rstrip('\n')
    print pass_url
    p.setopt(pycurl.URL, pass_url)
    p.perform()

    p.close() 
    pageContents.seek(0)
    print pageContents.readlines()

This throws an error, it cannot find the account members . 这将引发错误,无法找到帐户members

The variable mentioned url is of the form host_ip:port. 提到的url变量的形式为host_ip:port。

I have tried a lot to fix these errors. 我已经尝试了很多修复这些错误的方法。 I dont know where I am going wrong. 我不知道我要去哪里错了。 Any help would be appreciated. 任何帮助,将不胜感激。

a) string escaping a)字符串转义

For the subprocess/curl usage, you should be escaping your string tokens rather than manually adding extra ' : 对于子进程/卷曲的用法,您应该转义字符串标记,而不是手动添加额外的'

...stuff'+"'"+'more.stuff...

Escape using \\ before the character ie using 在字符前使用\\进行转义,即使用

"curl -X POST -H \\"Content-Type:application/json;charset=UTF-8\\""

will keep the " around the Content-Type section. 将在Content-Type部分附近保留"

More on escape characters here: Lexical Analysis - String Literals 有关转义字符的更多信息,请参见词法分析-字符串文字

...The backslash () character is used to escape characters that otherwise have a special meaning... ...反斜杠()字符用于转义具有特殊含义的字符...

b) popen b) popen

Looking at the popen docs their example uses shlex.split() to split their command line into args. 通过查看popen文档,他们的示例使用shlex.split()将命令行拆分为args。 shlex splits the string a bit differently: shlex将字符串拆分的方式有所不同:

print(bashCommand.split())
['curl', '-X', 'POST', '-H', '"Content-Type:application/json;charset=UTF-8"', '-u', 'nidhi:pswd', 'http://TEST_URL/a/groups/Administrators/members.add', '-d', '\'{"members":["TEST_USER@example.com"]}\'']

print(shlex.split(bashCommand))
['curl', '-X', 'POST', '-H', 'Content-Type:application/json;charset=UTF-8', '-u', 'nidhi:pswd', 'http://TEST_URL/a/groups/Administrators/members.add', '-d', '{"members":["TEST_USER@example.com"]}']

you can see shlex removes excess quoting. 您可以看到shlex删除了多余的报价。

c) http response code c)http响应码

Try using -I option in curl to get a HTTP response code back (and the rest of the HTTP headers): 尝试在curl使用-I选项以获取HTTP响应代码(以及其余的HTTP标头):

$curl -h
...
-I, --head          Show document info only

Even though you're using subprocess to start/make the request, it should still print the return value to the console(stdout). 即使您正在使用subprocess来启动/发出请求,它仍应将返回值打印到控制台(stdout)。

d) putting it all together d)全部放在一起

I changed the how the url and u_name are interpolated into the string. 我更改了将urlu_name插入字符串的方式。

import shlex
import subprocess


def add_user_to_administrator(u_name, url):
    bashCommand = "curl -I -X POST -H \"Content-Type:application/json;charset=UTF-8\" -u nidhi:pswd http://%(url)s/a/groups/Administrators/members.add -d '{\"members\":[\"%(u_n)s@example.com\"]}'"
    bashCommand = bashCommand % {'u_n': u_name, 'url': url}
    args = shlex.split(bashCommand)
    process = subprocess.Popen(args)

add_user_to_administrator('TEST_USER', 'TEST_URL')

If none of this helps, and you're getting no response from gerrit, I'd check gerrit logs to see what happens when it receives your request. 如果以上方法均无济于事,并且您没有收到gerrit的答复,我将检查gerrit日志以了解收到请求后会发生什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM