为什么在这个shell脚本中黑体不是URL编码?
我想对基于shell脚本的字符串进行编码。 我已经从网上下载了一个脚本。 它是:为什么在这个shell脚本中黑体不是URL编码?
#!/bin/sh
url_encoder()
{
echo -n "$1" | awk -v ORS="" '{ gsub(/./,"&\n") ; print }' | while read l;
do
case "$l" in
[-_.~/a-zA-Z0-9]) echo -n ${l} ;;
"") echo -n %20 ;;
*) printf '%%%02X' "'$l"
esac
done
}
echo ""
}
上述码的基本思想是 (1)转换输入串入行,每一行有一个字符 (2)对于每一行,URL编码字符
所以如果我运行
$url_encoder "abc:"
输出将是 “ABC%3A”,这是正确的
但是,如果我跑
$url_encoder "\\" # I want to encode the backslash, so I use 2 "\" here
根本没有输出。
你知道原因吗?
无需使用阅读这是缓慢的,可变的扩张可以做一个字符串,无需特别处理空格字符,它可以作为默认为什么反斜杠在前看不见的处理
url_encoder() {
local i str=$1 c
for ((i=0;i<${#str};i+=1)); do
c=${str:i:1}
case "$c" in
[-_.~/a-zA-Z0-9]) echo -n "${c}" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
}
l='\'
printf '%%%02X' "'$l"
原因因为它对read
有特殊含义,所以应该使用-r
选项来避免。
https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-read
注~
也应进行编码http://www.rfc-editor.org/rfc/rfc1738.txt
printf的说法开始报价(单人或双人),只处理ASCII字符 “'$ C”(< 128)。
url_encoder() { (
LC_ALL=C
str=$1
for ((i=0;i<${#str};i+=1)); do
c=${str:i:1}
if [[ $c = [-_./a-zA-Z0-9] ]]; then
echo -n "${c}"
elif [[ $c = [$'\1'-$'\x7f'] ]]; then
printf '%%%02X' "'$c"
else
printf '%%%s' $(echo -n "$c" | od -An -tx1)
fi
done
)}
是的,“读-r”的作品。感谢其他两个版本的url编码器。但它不是bash脚本,它是“#!/ bin/sh”,所以某些语法(例如for((i = 0; i AllenHu
使用'read'会导致其他问题IFS必须取消设置以区分空格,制表符和换行符,例如'IFS = read -r';然而它会很慢'sh'显然不是好工具 –
如果不能使用'bash'特定的问题这个问题不应该被标记'bash' –
Nahuel Fouilleul's helpful answer解释你的方法问题(-r
从您的read
命令丢失,造成\
字符不需要解释。),并提供了更有效的解决方案bash
。
这里的一个更有效的,符合POSIX的溶液(sh
兼容),其执行与单个awk
命令的编码,假定输入字符串由32之间仅在ASCII/Unicode码点范围内的字符127,包含性地:
#!/bin/sh
url_encoder()
{
awk -v url="$1" -v ORS= 'BEGIN {
# Create lookup table that maps characters to their code points.
for(n=32;n<=127;n++) ord[sprintf("%c",n)]=n
# Process characters one by one, either passing them through, if they
# need no encoding, or converting them to their %-prefixed hex equivalent.
for(i=1;i<=length(url);++i) {
char = substr(url, i, 1)
if (char !~ "[-_.~/a-zA-Z0-9]") char = sprintf("%%%x", ord[char])
print char
}
printf "\n"
}'
}
谁在使用'url_encoder'的输出?像'curl'或'wget'这样的东西应该有必要的方式来编码它的输入。 – chepner
url_encoder的输出应该按照要求先散列。 – AllenHu