【问题标题】:curl on macos problem with unicode characters使用 unicode 字符处理 macos 问题
【发布时间】:2021-12-02 22:25:54
【问题描述】:

我有在 MacOS 上运行的脚本 它使用 curl 来获取包含共享点站点上文件的 json。

一切正常,但在 bash 或 sh 中运行时 curl 的响应具有以 \uxxxx 格式写出的 unicode 字符。

for example ö is \u00f6
"Name":"\u00f6vning.dotx"

但是当使用 zsh 运行时,它会正确编码。

知道为什么,你能用 bash 或 sh 让它工作吗?

#!/bin/sh
url="https://company.sharepoint.com/sites/Testfiles"
folder="TestDocuments"

files=$(curl -s $url"/_api/web/GetFolderByServerRelativeUrl('Documents/"$folder"')/Files" -H "Accept: application/json")
echo $files

运行 curl -v 时

GET /sites/Testfiles/_api/web/GetFolderByServerRelativeUrl('Documents/TestDocuments')/Files HTTP/1.1
> Host: company.sharepoint.com
> User-Agent: curl/7.64.1
> Accept: application/json
> 
< HTTP/1.1 200 OK
< Cache-Control: private, max-age=0
< Transfer-Encoding: chunked
< Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8

这是完整的 json 响应

{
    "odata.metadata": "https://company.sharepoint.com/sites/Testfiles/_api/$metadata#SP.ApiData.Files12",
    "value": [
        {
            "odata.type": "SP.File",
            "odata.id": "https://company.sharepoint.com/sites/Testfiles/_api/Web/GetFileByServerRelativePath(decodedurl='/sites/Testfiles/Documents/TestDocs/\u00f6vning.dotx')",
            "odata.editLink": "Web/GetFileByServerRelativePath(decodedurl='/sites/Testfiles/Documents/TestDocs/%C3%B6vning.dotx')",
            "CheckInComment": "",
            "CheckOutType": 2,
            "ContentTag": "{39C1CD78-3674-49F4-9982-214B33FC03BE},2,5",
            "CustomizedPageStatus": 0,
            "ETag": "\"{39C1CD78-3674-49F4-9982-214B33FC03BE},2\"",
            "Exists": true,
            "IrmEnabled": false,
            "Length": "48725",
            "Level": 1,
            "LinkingUri": "https://company.sharepoint.com/sites/Testfiles/Documents/TestDocs/\u00f6vning.dotx?d=w11c1cd78361119f49982214b33fd43be",
            "LinkingUrl": "https://company.sharepoint.com/sites/Testfiles/Documents/TestDocs/\u00f6vning.dotx?d=w11c1cd78361119f49982214b33fd43be",
            "MajorVersion": 1,
            "MinorVersion": 0,
            "Name": "\u00f6vning.dotx",
            "ServerRelativeUrl": "/sites/Testfiles/Documents/TestDocs/\u00f6vning.dotx",
            "TimeCreated": "2021-10-14T13:32:16Z",
            "TimeLastModified": "2021-10-14T13:32:16Z",
            "Title": "",
            "UIVersion": 512,
            "UIVersionLabel": "1.0",
            "UniqueId": "39c1cd78-3674-49f4-9982-214b33fc03be"
        }
    ]
}

【问题讨论】:

  • 我在您的示例中看不到 ö 或任何非 ascii 字符。
  • 这就是ö 在 JSON 中的表示方式。
  • 添加了来自 curl 的 json 响应的样子

标签: bash macos curl unicode


【解决方案1】:

在 bash 和 zsh 上使用相同的命令:

printf "%b\n" "\u00f6vning.dotx"

【讨论】:

    【解决方案2】:

    bash 中,您需要使用-e 选项让echo\u 转义扩展为终端可以显示的UTF-8 序列。

    $ x='"\u00f6vning.dotx"'
    $ echo "$x"
    "\u00f6vning.dotx"
    $ echo -e "$x"
    "övning.dotx"
    

    首先,我们有一个“巧合”,即 JSON、bashzsh 使用相同的语法 (\u....) 来表示纯 ASCII 中的任意 Unicode 代码点。这对于一般的 POSIX 兼容的 shell 来说是正确的,所以我认为你不能期望在运行 sh 时,不管实际上是哪个 shell用过的。 (实际上,它不适用于bash 3.2,但适用于更高版本的bash。)

    zshecho 实现符合XSI,因为它默认扩展了各种字符序列。 (\u 本身不是由 XSI 定义的,但zsh 将它们包含在由echo 扩展的序列列表中。)(echo 的 POSIX 合规性相当宽松,仅说明可以处理包含反斜杠的参数一种特定于实现的方式。)

    bashecho 的实现默认 XSI 兼容。 -e 启用反斜杠序列的扩展,就像设置 xpg_echo shell 选项一样。

    $ shopt -s xpg_echo
    $ echo "$x"
    "övning.dotx"
    

    【讨论】:

    • 欢迎任何用于明确 POSIX 合规性如何影响 \u 解释的 cmets。为了准确起见,我已经重写了好几次。
    • POSIX 允许\u... 转义序列留有余地,只需声明结果是在echo 的任何操作数包含反斜杠字符时定义的实现,因此它根本不应该影响它们的解释。
    • 好点。需要符合 XSI 的系统来扩展 \a 等,但似乎也没有什么禁止扩展其他序列。
    • 感谢您的解释,我猜必须坚持使用 zsh
    • 不,您应该将curl 的输出视为:JSON。例如,通过jq '.Name' 管道输出,并使用您喜欢调用jq 的任何shell。
    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 2011-10-29
    • 2012-04-24
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多