我试图写一个bash脚本测试,需要一个参数,并通过curl发送到网站。我需要url编码的值,以确保特殊字符被正确处理。最好的方法是什么?
这是我到目前为止的基本脚本:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
我试图写一个bash脚本测试,需要一个参数,并通过curl发送到网站。我需要url编码的值,以确保特殊字符被正确处理。最好的方法是什么?
这是我到目前为止的基本脚本:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
当前回答
为了完整起见,许多使用sed或awk的解决方案只翻译一组特殊的字符,因此代码大小相当大,也不翻译其他应该编码的特殊字符。
urlencode的一个安全方法是对每个字节进行编码——即使是那些允许的字节。
echo -ne 'some random\nbytes' | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g'
XXD在这里小心地将输入处理为字节而不是字符。
编辑:
xxd附带了Debian中的vim-common包,我只是在一个没有安装它的系统上,我不想安装它。另一种选择是使用Debian中的bsdmainutils包中的hexdump。根据下图,bsdmainutils和vim-common应该有相同的可能性被安装:
http://qa.debian.org/popcon-png.php?packages=vim-common%2Cbsdmainutils&show_installed=1&want_legend=1&want_ticks=1
但是这里有一个使用hexdump代替XXD的版本,并且允许避免tr调用:
echo -ne 'some random\nbytes' | hexdump -v -e '/1 "%02x"' | sed 's/\(..\)/%\1/g'
其他回答
如果不想依赖Perl,也可以使用sed。这有点混乱,因为每个角色都必须单独转义。用以下内容创建一个文件,并将其命名为urlencode.sed
s/%/%25/g
s/ /%20/g
s/ /%09/g
s/!/%21/g
s/"/%22/g
s/#/%23/g
s/\$/%24/g
s/\&/%26/g
s/'\''/%27/g
s/(/%28/g
s/)/%29/g
s/\*/%2a/g
s/+/%2b/g
s/,/%2c/g
s/-/%2d/g
s/\./%2e/g
s/\//%2f/g
s/:/%3a/g
s/;/%3b/g
s//%3e/g
s/?/%3f/g
s/@/%40/g
s/\[/%5b/g
s/\\/%5c/g
s/\]/%5d/g
s/\^/%5e/g
s/_/%5f/g
s/`/%60/g
s/{/%7b/g
s/|/%7c/g
s/}/%7d/g
s/~/%7e/g
s/ /%09/g
要使用它,请执行以下操作。
STR1=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f1)
STR2=$(echo "https://www.example.com/change&$ ^this to?%checkthe@-functionality" | cut -d\? -f2)
OUT2=$(echo "$STR2" | sed -f urlencode.sed)
echo "$STR1?$OUT2"
这将把字符串分成需要编码的部分,而没问题的部分,编码需要它的部分,然后缝合在一起。
为了方便起见,你可以把它放在sh脚本中,也许让它带一个参数来编码,把它放在你的路径上,然后你可以调用:
urlencode https://www.exxample.com?isThisFun=HellNo
源
Python 3基于@sandro在2010年的好答案:
echo "Test & /me" | python -c "import urllib.parse;print (urllib.parse.quote(input()))"
测试% 20% 26% 20 /我
如果你想运行GET请求并使用纯curl,只需添加—得到@Jacob的解决方案。
这里有一个例子:
curl -v --get --data-urlencode "access_token=$(cat .fb_access_token)" https://graph.facebook.com/me/feed
安装php后,我使用这种方式:
URL_ENCODED_DATA=`php -r "echo urlencode('$DATA');"`
这是orwellophile回答的ksh版本,包含rawurlencode和rawurldecode函数(链接:如何为curl命令urlencode数据?)我没有足够的代表发表评论,因此有了新的帖子。
#!/bin/ksh93
function rawurlencode
{
typeset string="${1}"
typeset strlen=${#string}
typeset encoded=""
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) o=$(printf '%%%02x' "'$c")
esac
encoded+="${o}"
done
print "${encoded}"
}
function rawurldecode
{
printf $(printf '%b' "${1//%/\\x}")
}
print $(rawurlencode "C++") # --> C%2b%2b
print $(rawurldecode "C%2b%2b") # --> C++