拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Python子行程没有将大括号作为自变量传递?或者双引号的问题

Python子行程没有将大括号作为自变量传递?或者双引号的问题

白鹭 - 2022-01-24 2039 0 0

我在 python 子行程模块中遇到了 } 括号和双引号的问题。这是标准终端命令的示例:

curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Luke Skywalker", "role": "Jedi"}'

当我尝试像这样使用 subprocess 模块时: 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"}' 
       ^

任何帮助将不胜感激。提前致谢。

uj5u.com热心网友回复:

您需要了解 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 字符,但通常的做法是参考这样的长字符串。为了文体的一致性,-Hand POSTand -Xeven 也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 实作中有足够多的歧义,因此非常值得参考它们。例如,符合 posix 的 shell 将cmd {a,b}通过cmd使用string呼叫来执行该字符串{a,b},但是bash(即使使用 --posix )将cmd使用两个自变量a和 进行呼叫b这在这里是相关的,因为 json 包含 a,并且如果没有参考该自变量,则不同的 shell 将对其进行不同的决议。如有疑问,请使用引号。并且始终参考您的变量,除非有特定原因不参考。

uj5u.com热心网友回复:

串列中的每一项都是被呼叫行程的一个自变量。您可以看到,您用作'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]

我把资料做成了一个变量,所以你可以很容易地转义它。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *