【问题标题】:URL encoding a string in shell script in a portable way以可移植方式对 shell 脚本中的字符串进行 URL 编码
【发布时间】:2016-10-27 04:22:07
【问题描述】:

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

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

注意事项:

  • 问题“URL encoding a string in bash script”要求提供特定于 Bash 的脚本,唯一提供的答案取决于容器上安装的 PHP。

  • 问题“How to urlencode data for curl command?”是特定于 curl 的,但当然可以接受非特定的答案。但是,这 25 个答案似乎都不适用。那里的答案之一仅适用于将数据发送到 curl,而有些特定于 bashksh,有些则需要 Perl PHPPythonLuaNodeJSRubygridsite-clientsuni2asciijqawksed。其中之一不需要额外的依赖,但不保留a1~ 等字符。

我期望拥有的:

$> 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

【问题讨论】:

标签: linux shell posix urlencode


【解决方案1】:

以下功能已在 BusyBox AshDashBashZSH 中测试。

它们只使用 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,以便每个字符将在自己的行中)
  • 这里的文档&lt;&lt;EOFfold 的输出提供给read 命令
  • while 命令一次接受来自read 命令的一行(仅1 个字符宽),该命令从fold 获取输入,并将其分配给变量c
  • case 测试该字符是否需要进行 url 编码。如果没有,则打印出来,while 循环继续
  • od 将每个输入字符转换为十六进制
  • tr 将空格转换为% 并加入多行

【讨论】:

  • 很好,虽然它不是完全可移植的,因为od 的输出与您在非 Linux 环境中的期望不同。对我来说,urlencode ' ' 返回%%%%%%%%%%%20%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%。用sed 's/ */%/g;s/%$//' 替换第一个tr 似乎有帮助,但它仍然无法将\n 转换为%0d
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 2017-09-23
相关资源
最近更新 更多