URL 以可移植的方式在 shell 脚本中编码字符串

URL encoding a string in shell script in a portable way

我需要 URL 使用 shell 函数对字符串进行编码,该函数将在 BusyBox Ash、Dash、Bash 和 ZSH 中 运行。

它会 运行 在不同的 Docker 容器中,因此最好安装尽可能少的依赖项。

备注:

我希望得到的:

$> urlencode '/'
%2f

$> urlencode 'ç'
%c3%a7

$> urlencode '*'
%2a

$> urlencode abc-123~6
abc-123~6

$> urlencode 'a test ?*ç '
a%20test%20%3f%2a%c3%a7%20

以下功能已在BusyBox AshDashBash[=42中测试=] 和 ZSH.

它们只使用 shell 内置命令或核心命令,应该也适用于其他 shell。

urlencodepipe() {
  local LANG=C; local c; while IFS= read -r c; do
    case $c in [a-zA-Z0-9.~_-]) printf "$c"; continue ;; esac
    printf "$c" | od -An -tx1 | tr ' ' % | tr -d '\n'
  done <<EOF
$(fold -w1)
EOF
  echo
}

urlencode() { printf "$*" | urlencodepipe ;}

工作原理:

  • 标准输入由 fold -w1 处理,它 重新格式化 其输入,使其为 1 列宽(换句话说,它添加了 \n 在每个输入字符之后,以便每个字符都在自己的行上)
  • 此处文档 <<EOFfold 的输出提供给 read 命令
  • while 命令一次接受来自 read 命令的一行(只有 1 个字符宽),read 命令从 fold 获取输入,并将其分配给变量 c
  • case 测试该字符是否需要 url 编码。如果没有,则打印它并继续 while 循环
  • od 将每个输入字符转换为十六进制
  • tr 将空格转换为 % 并连接多行