本文翻译自:How to urlencode data for curl command?
I am trying to write a bash script for testing that takes a parameter and sends it through curl to web site. 我正在尝试编写一个bash脚本进行测试,该脚本接受一个参数并将其通过curl发送到网站。 I need to url encode the value to make sure that special characters are processed properly. 我需要对值进行url编码,以确保正确处理特殊字符。 What is the best way to do this? 做这个的最好方式是什么?
Here is my basic script so far: 到目前为止,这是我的基本脚本:
#!/bin/bash
host=${1:?'bad host'}
value=$2
shift
shift
curl -v -d "param=${value}" http://${host}/somepath $@
#1楼
参考:https://stackoom.com/question/1F8q/如何为curl命令添加数据
#2楼
Here is the pure BASH answer. 这是纯BASH答案。
rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}" # You can either set a return variable (FASTER)
REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
}
You can use it in two ways: 您可以通过两种方式使用它:
easier: echo http://url/q?=$( rawurlencode "$args" )
faster: rawurlencode "$args"; echo http://url/q?${REPLY}
[edited] [编辑]
Here's the matching rawurldecode() function, which - with all modesty - is awesome. 这是匹配的rawurldecode()函数,尽管非常谦虚,它还是很棒的。
# Returns a string in which the sequences with percent (%) signs followed by
# two hex digits have been replaced with literal characters.
rawurldecode() {
# This is perhaps a risky gambit, but since all escape characters must be
# encoded, we can replace %NN with \xNN and pass the lot to printf -b, which
# will decode hex for us
printf -v REPLY '%b' "${1//%/\\x}" # You can either set a return variable (FASTER)
echo "${REPLY}" #+or echo the result (EASIER)... or both... :p
}
With the matching set, we can now perform some simple tests: 有了匹配集,我们现在可以执行一些简单的测试:
$ diff rawurlencode.inc.sh \
<( rawurldecode "$( rawurlencode "$( cat rawurlencode.inc.sh )" )" ) \
&& echo Matched
Output: Matched
And if you really really feel that you need an external tool (well, it will go a lot faster, and might do binary files and such...) I found this on my OpenWRT router... 而且,如果您真的感觉到需要外部工具(嗯,它将运行得更快,并且可能会生成二进制文件等),我在OpenWRT路由器上发现了这一点...
replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
Where url_escape.sed was a file that contained these rules: 其中url_escape.sed是包含以下规则的文件:
# sed url escaping
s:%:%25:g
s: :%20:g
s:<:%3C:g
s:>:%3E:g
s:#:%23:g
s:{:%7B:g
s:}:%7D:g
s:|:%7C:g
s:\\:%5C:g
s:\^:%5E:g
s:~:%7E:g
s:\[:%5B:g
s:\]:%5D:g
s:`:%60:g
s:;:%3B:g
s:/:%2F:g
s:?:%3F:g
s^:^%3A^g
s:@:%40:g
s:=:%3D:g
s:&:%26:g
s:\$:%24:g
s:\!:%21:g
s:\*:%2A:g
#3楼
One of variants, may be ugly, but simple: 变体之一可能很丑陋,但很简单:
urlencode() {
local data
if [[ $# != 1 ]]; then
echo "Usage: $0 string-to-urlencode"
return 1
fi
data="$(curl -s -o /dev/null -w %{url_effective} --get --data-urlencode "$1" "")"
if [[ $? != 3 ]]; then
echo "Unexpected error" 1>&2
return 2
fi
echo "${data##/?}"
return 0
}
Here is the one-liner version for example (as suggested by Bruno ): 例如,这是单线版本(由Bruno建议):
date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-
# If you experience the trailing %0A, use
date | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | sed -E 's/..(.*).../\1/'
#4楼
Ruby,为了完整性
value="$(ruby -r cgi -e 'puts CGI.escape(ARGV[0])' "$2")"
#5楼
uni2ascii is very handy: uni2ascii非常方便:
$ echo -ne '你好世界' | uni2ascii -aJ
%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C
#6楼
I've found the following snippet useful to stick it into a chain of program calls, where URI::Escape might not be installed: 我发现以下片段有助于将其粘贴到程序调用链中,其中可能未安装URI :: Escape:
perl -p -e 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg'