Python 子进程没有将大括号作为参数传递?或者双引号的问题
Python subprocess not passing curly brackets as arguments? Or a problem with double quotes
我对 python 子流程模块中的 } 括号和双引号有疑问。
这是标准终端命令的示例:
curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Luke Skywalker", "role": "Jedi"}'
当我尝试像这样使用子进程模块时:
1.
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
"'{",
"name:",
'"Luke Skywalker"',
'"role:"',
'"Jedi"',
"}'",
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我得到:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 126 0 124 100 2 4225 68 --:--:-- --:--:-- --:--:-- 5727
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (6) Could not resolve host: "Jedi"
curl: (3) unmatched close brace/bracket in URL position 1:
}'
^
还有这个:
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
'\'{"name":',
'"Luke Skywalker"',
'"role:"',
' "Jedi"}\' ',
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我得到:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 133 0 124 100 9 2699 195 --:--:-- --:--:-- --:--:-- 3325
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
curl: (3) unmatched close brace/bracket in URL position 8:
"Jedi"}'
^
如有任何帮助,我们将不胜感激。提前致谢。
您需要了解 shell 是如何解析命令的。当你执行:
curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Luke Skywalker", "role": "Jedi"}'
curl
的参数是:-X
、POST
、localhost:8080/employees
、-H
、Content-type:application/json
、-d
, 和 {"name": "Luke Skywalker", "role": "Jedi"}
shell 调用中单引号的作用是将整个字符串保留为文字参数,并防止它被空格分割。此外,它是一种在参数中传递双引号并防止它们被 shell 视为引号字符的机制。 Content-type:application/json
周围的单引号是不必要的,因为该字符串不包含 shell 的任何特殊字符,但通常的做法是像这样引用较长的字符串。为了文体的一致性,-H
and POST
and -X
甚至 curl
也应该被引用,但是大多数坚持“如果你不理解 shell" 风格很少采用那种程度的一致性。 curl
从来没有看到单引号,试图将它们传递到 Python 的参数列表中是一个错误。最初的 curl
命令也可以在 shell 中调用为:
'curl' "-X" PO""ST lo'cal'"host:8080/emp"loyees -"H" Content-type:application/json -d \{\"name\":\ \"Luke\ Skywalker\"\,\ \"role\":\ \"Jedi\"\}
shell 中的引用是(也许)值得研究一下以了解的东西。需要理解的重要一点是,(未转义的)引号(双引号和单引号,但每个引号的规则略有不同)被 shell 删除,因此被调用的应用程序永远不会看到它们。
请注意,我在引用上面有点轻率。引用字符串 Content-type:application/json
是完全合理的,因为不值得花时间来决定 :
和 /
是否对 shell 是特殊的。它们不是,但是 shell 实现中有足够的歧义,非常值得引用它们。例如,符合 posix 的 shell 将通过使用字符串 {a,b}
调用 cmd
来执行字符串 cmd {a,b}
,但是 bash
(即使使用 - -posix) 将使用两个参数 a
和 b
调用 cmd
。这在这里是相关的,因为 json 包含一个 ,
并且如果不引用该参数,则该参数将被不同的 shell 以不同方式解析。如有疑问,请使用引号。除非有特殊原因,否则请始终引用您的变量。
列表中的每一项都是调用进程的参数。您可以看到,您使用 'Content-type:application/json'
作为单个参数。同样,您也可以使用 json。
见下文:
payload = '{"name":"Luke Skywalker","role:"Jedi"}'
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
f"'{payload}'"
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我把数据做了一个变量,所以你可以很容易地转义它。
我对 python 子流程模块中的 } 括号和双引号有疑问。 这是标准终端命令的示例:
curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Luke Skywalker", "role": "Jedi"}'
当我尝试像这样使用子进程模块时: 1.
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
"'{",
"name:",
'"Luke Skywalker"',
'"role:"',
'"Jedi"',
"}'",
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我得到:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 126 0 124 100 2 4225 68 --:--:-- --:--:-- --:--:-- 5727
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (6) Could not resolve host: "Jedi"
curl: (3) unmatched close brace/bracket in URL position 1:
}'
^
还有这个:
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
'\'{"name":',
'"Luke Skywalker"',
'"role:"',
' "Jedi"}\' ',
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我得到:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 133 0 124 100 9 2699 195 --:--:-- --:--:-- --:--:-- 3325
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
curl: (3) unmatched close brace/bracket in URL position 8:
"Jedi"}'
^
如有任何帮助,我们将不胜感激。提前致谢。
您需要了解 shell 是如何解析命令的。当你执行:
curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Luke Skywalker", "role": "Jedi"}'
curl
的参数是:-X
、POST
、localhost:8080/employees
、-H
、Content-type:application/json
、-d
, 和 {"name": "Luke Skywalker", "role": "Jedi"}
shell 调用中单引号的作用是将整个字符串保留为文字参数,并防止它被空格分割。此外,它是一种在参数中传递双引号并防止它们被 shell 视为引号字符的机制。 Content-type:application/json
周围的单引号是不必要的,因为该字符串不包含 shell 的任何特殊字符,但通常的做法是像这样引用较长的字符串。为了文体的一致性,-H
and POST
and -X
甚至 curl
也应该被引用,但是大多数坚持“如果你不理解 shell" 风格很少采用那种程度的一致性。 curl
从来没有看到单引号,试图将它们传递到 Python 的参数列表中是一个错误。最初的 curl
命令也可以在 shell 中调用为:
'curl' "-X" PO""ST lo'cal'"host:8080/emp"loyees -"H" Content-type:application/json -d \{\"name\":\ \"Luke\ Skywalker\"\,\ \"role\":\ \"Jedi\"\}
shell 中的引用是(也许)值得研究一下以了解的东西。需要理解的重要一点是,(未转义的)引号(双引号和单引号,但每个引号的规则略有不同)被 shell 删除,因此被调用的应用程序永远不会看到它们。
请注意,我在引用上面有点轻率。引用字符串 Content-type:application/json
是完全合理的,因为不值得花时间来决定 :
和 /
是否对 shell 是特殊的。它们不是,但是 shell 实现中有足够的歧义,非常值得引用它们。例如,符合 posix 的 shell 将通过使用字符串 {a,b}
调用 cmd
来执行字符串 cmd {a,b}
,但是 bash
(即使使用 - -posix) 将使用两个参数 a
和 b
调用 cmd
。这在这里是相关的,因为 json 包含一个 ,
并且如果不引用该参数,则该参数将被不同的 shell 以不同方式解析。如有疑问,请使用引号。除非有特殊原因,否则请始终引用您的变量。
列表中的每一项都是调用进程的参数。您可以看到,您使用 'Content-type:application/json'
作为单个参数。同样,您也可以使用 json。
见下文:
payload = '{"name":"Luke Skywalker","role:"Jedi"}'
test = subprocess.Popen(
[
"curl",
"-X",
"POST",
"localhost:8080/employees",
"-H",
"'Content-type:application/json'",
"-d",
f"'{payload}'"
],
stdout=subprocess.PIPE,
)
output = test.communicate()[0]
我把数据做了一个变量,所以你可以很容易地转义它。