我试图写一个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 $@
当前回答
Ruby,为了完整性
value="$(ruby -r cgi -e 'puts CGI.escape(ARGV[0])' "$2")"
其他回答
以下是基于奥威尔的回答,但解决了多字节 通过设置LC_ALL=C (vte.sh的一个技巧)在评论中提到的错误。 我把它写成了函数PROMPT_COMMAND的形式,因为 我就是这么用的。
print_path_url() {
local LC_ALL=C
local string="$PWD"
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
printf "\033]7;file://%s%s\007" "${HOSTNAME:-}" "${encoded}"
}
另一个选择是使用jq:
$ printf %s 'input text'|jq -sRr @uri
input%20text
$ jq -rn --arg x 'input text' '$x|@uri'
input%20text
-r(——raw-output)输出字符串的原始内容,而不是JSON字符串字面量。-n(——null-input)不从STDIN读取输入。
-R(——raw-input)将输入行视为字符串,而不是将其解析为JSON,而-sR(——slurp——raw-input)将输入读入单个字符串。如果你的输入只包含一行,或者你不想用%0A替换换行符,你可以用-Rr替换-sRr:
$ printf %s\\n multiple\ lines of\ text|jq -Rr @uri
multiple%20lines
of%20text
$ printf %s\\n multiple\ lines of\ text|jq -sRr @uri
multiple%20lines%0Aof%20text%0A
或者这个百分比编码所有字节:
xxd -p|tr -d \\n|sed 's/../%&/g'
这可能是最好的一个:
after=$(echo -e "$before" | od -An -tx1 | tr ' ' % | xargs printf "%s")
Python 3基于@sandro在2010年的好答案:
echo "Test & /me" | python -c "import urllib.parse;print (urllib.parse.quote(input()))"
测试% 20% 26% 20 /我
其中一种变体可能很丑,但很简单:
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
}
下面是一个单行版本的例子(由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/'