想要通过 python 的子进程或 pycurl 运行 curl 命令
Want to run a curl command either through python's subprocess or pycurl
我有以下命令将用户添加到 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"]}'
当我在我的终端上 运行 这个命令时,它 运行 完美地给出了预期的输出。
但是,我想在 python 中使用 subprocess
或 pycurl
库执行此命令。
使用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())
没有显示错误,但在管理员组中没有看到任何变化。
我使用 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()
这会引发错误,找不到帐户 members
。
提到的变量 url
的形式是 host_ip:port。
我已经尝试了很多来修复这些错误。我不知道我哪里错了。任何帮助,将不胜感激。
- 你应该尝试 [
urllib2
] (python2
) 或 urllib
(python3
) 到 post json 数据;
- for
subprocess.Popen
: subprocess.Popen.communicate
(https://docs.python.org/3.5/library/subprocess.html?highlight=subprocess#subprocess.Popen.communicate) 可能会给你帮助,或者只是在 shell 中执行 bashCommand 以查看差异;
- 对于
pycurl
,我没有使用过,请补充错误信息。
a) 字符串转义
对于 subprocess/curl 用法,您应该转义字符串标记而不是手动添加额外的 '
:
...stuff'+"'"+'more.stuff...
在字符前使用 \
进行转义,即使用
"curl -X POST -H \"Content-Type:application/json;charset=UTF-8\""
将在 Content-Type 部分保留 "
。
更多关于转义字符的信息:Lexical Analysis - String Literals
...The backslash () character is used to escape characters that otherwise have a special meaning...
b) popen
正在查看 popen
docs their example uses shlex.split()
以将其命令行拆分为参数。 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"]}']
您可以看到 shlex
删除了多余的引号。
c) http 响应代码
尝试使用 curl
中的 -I
选项来获取返回的 HTTP 响应代码(以及 HTTP headers 的其余部分):
$curl -h
...
-I, --head Show document info only
即使您使用 subprocess
来 start/make 请求,它仍应将 return 值打印到控制台(stdout)。
d) 把它们放在一起
我更改了 url
和 u_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')
如果 none 有帮助,并且您没有收到 gerrit 的响应,我会检查 gerrit 日志,看看它收到您的请求时会发生什么。
我有以下命令将用户添加到 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"]}'
当我在我的终端上 运行 这个命令时,它 运行 完美地给出了预期的输出。
但是,我想在 python 中使用 subprocess
或 pycurl
库执行此命令。
使用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())
没有显示错误,但在管理员组中没有看到任何变化。
我使用 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()
这会引发错误,找不到帐户 members
。
提到的变量 url
的形式是 host_ip:port。
我已经尝试了很多来修复这些错误。我不知道我哪里错了。任何帮助,将不胜感激。
- 你应该尝试 [
urllib2
] (python2
) 或urllib
(python3
) 到 post json 数据; - for
subprocess.Popen
:subprocess.Popen.communicate
(https://docs.python.org/3.5/library/subprocess.html?highlight=subprocess#subprocess.Popen.communicate) 可能会给你帮助,或者只是在 shell 中执行 bashCommand 以查看差异; - 对于
pycurl
,我没有使用过,请补充错误信息。
a) 字符串转义
对于 subprocess/curl 用法,您应该转义字符串标记而不是手动添加额外的 '
:
...stuff'+"'"+'more.stuff...
在字符前使用 \
进行转义,即使用
"curl -X POST -H \"Content-Type:application/json;charset=UTF-8\""
将在 Content-Type 部分保留 "
。
更多关于转义字符的信息:Lexical Analysis - String Literals
...The backslash () character is used to escape characters that otherwise have a special meaning...
b) popen
正在查看 popen
docs their example uses shlex.split()
以将其命令行拆分为参数。 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"]}']
您可以看到 shlex
删除了多余的引号。
c) http 响应代码
尝试使用 curl
中的 -I
选项来获取返回的 HTTP 响应代码(以及 HTTP headers 的其余部分):
$curl -h
...
-I, --head Show document info only
即使您使用 subprocess
来 start/make 请求,它仍应将 return 值打印到控制台(stdout)。
d) 把它们放在一起
我更改了 url
和 u_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')
如果 none 有帮助,并且您没有收到 gerrit 的响应,我会检查 gerrit 日志,看看它收到您的请求时会发生什么。