如果我试图传递一个包含括号的URL给curl,它会失败并报错:

$ curl 'http://www.google.com/?TEST[]=1'
curl: (3) [globbing] illegal character in range specification at pos 29

然而,如果我转义两个括号,它似乎工作:

$ curl 'http://www.google.com/?TEST\[\]=1'

我怎么解决这个问题?是否有自动转义url的参数,或在传递到curl之前需要转义的字符的描述?


当前回答

在文档中是这样写的:

globbing字母 curl命令行工具支持url的“globbing”。这意味着您可以使用[N-M]和{1,2,3}序列创建范围和列表。用于此([]{})的字母在RFC 3986中保留,因此不能合法地成为此类URL的一部分。 然而,它们在WHATWG规范中并不是保留的或特殊的,所以通配符会弄乱这样的url。在这种情况下可以关闭Globbing(使用——globoff)。

这意味着您应该对保留/特殊字符(:/?#[]@!$&'()*+,;=)进行百分比编码,以避免它们的特殊解释。为此,在ASCII表中放入百分号(%)和十六进制字符值。例如:

Symbol Encoded Value
[ %5B
] %5D
{ %7B
} %7D

curl不期望URL中的保留/特殊字符,这四个符号用于生成多个URL (globbing操作):

$ curl http://localhost:8080/?TEST[a-c]=1

意志相当于

$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTb=1
$ curl http://localhost:8080/?TESTc=1

and

$ curl http://localhost:8080/?TEST{a,c,e}=1

意志相当于

$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTc=1
$ curl http://localhost:8080/?TESTe=1

如果你想禁用通配符操作:

encode them: $ curl http://localhost:8080/?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/?TEST%7Ba,c,e%7d=1 For zsh (default shell on Mac OS X) you must escape ? as well. Thus for both bash and zsh shells: $ curl http://localhost:8080/\?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/\?TEST%7Ba,c,e%7d=1 or use -g/--globoff option: $ curl -g http://localhost:8080/?TEST[a-c]=1 $ curl -g http://localhost:8080/?TEST{a,c,e}=1 # not enough, see note below ☝ In last example there is a caveat: globbing may be done by bash and zsh shell. To avoid globbing by shell: either escape characters putting reverse slash (\) (don't forget about escaping ? for zsh shell): $ curl -g http://localhost:8080/\?TEST\[a-c\]=1 $ curl -g http://localhost:8080/\?TEST\{a,c,e\}=1 or put URL in quotes (single or double): $ curl -g 'http://localhost:8080/?TEST[a-c]=1' $ curl -g 'http://localhost:8080/?TEST{a,c,e}=1'

此外,还要注意空方括号([])不会导致curl中的通配符:

$ curl 'http://localhost:8080/?TEST[]=1'

will request /?TEST[]=1。

对于空花括号({})则不是这样:

$ curl 'http://localhost:8080/?TEST{}=1'
curl: (3) empty string within braces in URL position 29:
http://localhost:8080/?TEST{}=1
                            ^

它们必须至少包含一个字符串。


P.S.你可以在docker上测试(按Ctrl+C退出):

$ docker run --rm -p 8080:80 -it nginx

并在单独的终端对其运行curl:

$ curl http://localhost:8080/?TEST[a-c]=1

在日志中,您应该看到为请求生成URL:

172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTa=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTb=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTc=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"

其他回答

我得到这个错误,虽然没有(明显的)括号在我的URL,在我的情况下——globoff命令不会解决这个问题。

例如(在mac上的iTerm2中执行此操作):

for endpoint in $(grep some_string output.txt); do curl "http://1.2.3.4/api/v1/${endpoint}" ; done

我有grep别名为“grep -color=always”。结果,上面的命令会导致这个错误,some_string会以你设置的grep的颜色高亮显示:

curl: (3) bad range in URL position 31:
http://1.2.3.4/api/v1/lalalasome_stringlalala

终端透明地将[color \codes]some_string[color \codes]转换为在终端中查看时预期的无特殊字符URL,但在幕后,颜色代码被发送在URL中传递给curl,导致URL中出现括号。

解决方案是不使用匹配高亮显示。

在文档中是这样写的:

globbing字母 curl命令行工具支持url的“globbing”。这意味着您可以使用[N-M]和{1,2,3}序列创建范围和列表。用于此([]{})的字母在RFC 3986中保留,因此不能合法地成为此类URL的一部分。 然而,它们在WHATWG规范中并不是保留的或特殊的,所以通配符会弄乱这样的url。在这种情况下可以关闭Globbing(使用——globoff)。

这意味着您应该对保留/特殊字符(:/?#[]@!$&'()*+,;=)进行百分比编码,以避免它们的特殊解释。为此,在ASCII表中放入百分号(%)和十六进制字符值。例如:

Symbol Encoded Value
[ %5B
] %5D
{ %7B
} %7D

curl不期望URL中的保留/特殊字符,这四个符号用于生成多个URL (globbing操作):

$ curl http://localhost:8080/?TEST[a-c]=1

意志相当于

$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTb=1
$ curl http://localhost:8080/?TESTc=1

and

$ curl http://localhost:8080/?TEST{a,c,e}=1

意志相当于

$ curl http://localhost:8080/?TESTa=1
$ curl http://localhost:8080/?TESTc=1
$ curl http://localhost:8080/?TESTe=1

如果你想禁用通配符操作:

encode them: $ curl http://localhost:8080/?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/?TEST%7Ba,c,e%7d=1 For zsh (default shell on Mac OS X) you must escape ? as well. Thus for both bash and zsh shells: $ curl http://localhost:8080/\?TEST%5Ba-c%5D=1 $ curl http://localhost:8080/\?TEST%7Ba,c,e%7d=1 or use -g/--globoff option: $ curl -g http://localhost:8080/?TEST[a-c]=1 $ curl -g http://localhost:8080/?TEST{a,c,e}=1 # not enough, see note below ☝ In last example there is a caveat: globbing may be done by bash and zsh shell. To avoid globbing by shell: either escape characters putting reverse slash (\) (don't forget about escaping ? for zsh shell): $ curl -g http://localhost:8080/\?TEST\[a-c\]=1 $ curl -g http://localhost:8080/\?TEST\{a,c,e\}=1 or put URL in quotes (single or double): $ curl -g 'http://localhost:8080/?TEST[a-c]=1' $ curl -g 'http://localhost:8080/?TEST{a,c,e}=1'

此外,还要注意空方括号([])不会导致curl中的通配符:

$ curl 'http://localhost:8080/?TEST[]=1'

will request /?TEST[]=1。

对于空花括号({})则不是这样:

$ curl 'http://localhost:8080/?TEST{}=1'
curl: (3) empty string within braces in URL position 29:
http://localhost:8080/?TEST{}=1
                            ^

它们必须至少包含一个字符串。


P.S.你可以在docker上测试(按Ctrl+C退出):

$ docker run --rm -p 8080:80 -it nginx

并在单独的终端对其运行curl:

$ curl http://localhost:8080/?TEST[a-c]=1

在日志中,您应该看到为请求生成URL:

172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTa=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTb=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"
172.17.0.1 - - [17/Jan/2023:09:21:53 +0000] "GET /?TESTc=1 HTTP/1.1" 200 615 "-" "curl/7.86.0" "-"

Globbing使用括号,因此需要用斜杠\来转义它们。或者,下面的命令行开关将禁用globbing:

——globoff(或短选项版本:-g)

Ex:

curl --globoff https://www.google.com?test[]=1

在命令中添加-g:

-g, --globoff
      This option switches off the "URL globbing parser". When you set this option, you can
      specify URLs that contain the letters {}[] without having curl itself interpret them.
      Note that these letters are not normal legal URL contents but they should be encoded
      according to the URI standard.

      Example:
       curl -g "https://example.com/{[]}}}}"

curl.se / docs / manpage.html # - g

以上答案都不适合我,我必须用%5B和%5D替换所有的开始/结束括号。

[——> %5B和for .

——> % 5d

我最初的curl url是这样的

https://test.com/computer/agent1/api/json?pretty=true&tree=executors [currentExecutable [url]

现在我这样用

https://test.com/computer/agent1/api/json?pretty=true&tree=executors%5BcurrentExecutable%5Burl%5D%5D