我试图写一个bash脚本测试,需要一个参数,并通过curl发送到网站。我需要url编码的值,以确保特殊字符被正确处理。最好的方法是什么?

这是我到目前为止的基本脚本:

#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@

当前回答

这可能是最好的一个:

after=$(echo -e "$before" | od -An -tx1 | tr ' ' % | xargs printf "%s")

其他回答

我发现下面的代码片段很有用,可以将它插入到一个程序调用链中,其中URI::Escape可能没有安装:

perl -p -e 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg'

(源)

另一种php方法:

echo "encode me" | php -r "echo urlencode(file_get_contents('php://stdin'));"

这个基于nodejs的答案将在stdin上使用encodeURIComponent:

uriencode_stdin() {
    node -p 'encodeURIComponent(require("fs").readFileSync(0))'
}

echo -n $'hello\nwörld' | uriencode_stdin
hello%0Aw%C3%B6rld

使用curl——data-urlencode;来自man curl:

它发布数据,类似于其他——data选项,不同的是它执行url编码。为了与cgi兼容,<data>部分应该以名称开头,后面跟着分隔符和内容规范。

使用示例:

curl \
    --data-urlencode "paramName=value" \
    --data-urlencode "secondParam=value" \
    http://example.com

有关更多信息,请参阅手册页。

这需要curl 7.18.0或更新版本(发布于2008年1月)。使用curl -V来检查您拥有的版本。

你也可以对查询字符串进行编码:

curl --get \
    --data-urlencode "p1=value 1" \
    --data-urlencode "p2=value 2" \
    http://example.com
    # http://example.com?p1=value%201&p2=value%202

下面是一个使用Lua的单行转换,类似于blueyed的答案,除了所有的RFC 3986 Unreserved Characters都没有被编码(就像这个答案):

url=$(echo 'print((arg[1]:gsub("([^%w%-%.%_%~])",function(c)return("%%%02X"):format(c:byte())end)))' | lua - "$1")

此外,您可能需要确保字符串中的换行符从LF转换为CRLF,在这种情况下,您可以插入一个gsub("\r? "“\n”,“\r\n”)在百分比编码之前。

下面是一个变体,在application/x-www-form-urlencoded的非标准风格中,它执行换行规范化,并将空格编码为'+'而不是'%20'(可以使用类似的技术将其添加到Perl代码片段中)。

url=$(echo 'print((arg[1]:gsub("\r?\n", "\r\n"):gsub("([^%w%-%.%_%~ ]))",function(c)return("%%%02X"):format(c:byte())end):gsub(" ","+"))' | lua - "$1")