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

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

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

当前回答

下面是我的嵌入式系统busybox ash shell版本,我最初采用了Orwellophile的变体:

urlencode()
{
    local S="${1}"
    local encoded=""
    local ch
    local o
    for i in $(seq 0 $((${#S} - 1)) )
    do
        ch=${S:$i:1}
        case "${ch}" in
            [-_.~a-zA-Z0-9]) 
                o="${ch}"
                ;;
            *) 
                o=$(printf '%%%02x' "'$ch")                
                ;;
        esac
        encoded="${encoded}${o}"
    done
    echo ${encoded}
}

urldecode() 
{
    # urldecode <string>
    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

其他回答

Ruby,为了完整性

value="$(ruby -r cgi -e 'puts CGI.escape(ARGV[0])' "$2")"

Python 3基于@sandro在2010年的好答案:

echo "Test & /me" | python -c "import urllib.parse;print (urllib.parse.quote(input()))"

测试% 20% 26% 20 /我

问题是关于在bash中这样做,不需要python或perl,因为实际上有一个命令,它完全是你想要的-“urlencode”。

value=$(urlencode "${2}")

这也更好,因为上面的perl答案,例如,没有正确编码所有字符。尝试使用从Word中获得的长破折号,你会得到错误的编码。

注意,你需要安装"gridsite-clients"来提供这个命令:

sudo apt install gridsite-clients

你可以在perl中模拟javascript的encodeURIComponent。下面是命令:

perl -pe 's/([^a-zA-Z0-9_.!~*()'\''-])/sprintf("%%%02X", ord($1))/ge'

你可以在.bash_profile中设置它为bash别名:

alias encodeURIComponent='perl -pe '\''s/([^a-zA-Z0-9_.!~*()'\''\'\'''\''-])/sprintf("%%%02X",ord($1))/ge'\'

现在你可以管道到encodeURIComponent:

$ echo -n 'hèllo wôrld!' | encodeURIComponent
h%C3%A8llo%20w%C3%B4rld!

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

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

(源)