【问题标题】:Strange characters appearing in bash variable expansionbash变量扩展中出现的奇怪字符
【发布时间】:2017-10-11 03:14:29
【问题描述】:

尝试在 contos7 上按我的预期执行以下操作:

pod_in_question=$(curl -u uname:password -k very.cluster.com/api/v1/namespaces/default/pods/ | grep -i '"name": "myapp-' | cut -d '"' -f 4)

echo "$pod_in_question"

curl -u uname:password -k -X DELETE "very.cluster.com/api/v1/namespaces/default/pods/${pod_in_question}"

但是,在 MacOS (10.12.1) 上尝试相同的操作会产生:

curl:(3) [globbing] 第 92 列中的错误范围

当我尝试 curl 使用 -g 选项的最后一行时,它会替换为格式错误的名称,例如:myapp-\\x1b[m\\x1b[Kl1eti\

echo 语句总是可以正常执行并显示类似myapp-v7454 的内容,我稍后想将其放入最后一个 curl 语句中。那么这些其他角色是从哪里来的呢?

【问题讨论】:

  • 如果有更多信息会很好,因为您的示例都不可重复。在 Mac 上,pod_in_question 有什么价值?也许存在字符编码问题。如果是这样,您可以通过iconv 翻译它。但是您在最后一部分显示的替换看起来像是您注入的一个调用ANSI escape sequencesgrep 可能没有检测到非 TTY 输出并且正在着色。尝试将 --color=never 参数添加到 grep
  • @paddy 更新了更多信息
  • 你需要调试你的调用链。这些转义序列设置屏幕模式并擦除行。使用echo 将其输出到支持转义序列的终端会有 appearance 没问题。相反,您为什么不通过echo "$pod_in_question" | hexdump -C 检验您的价值。
  • 我同意 paddy - hexdump 会提供非常丰富的信息。其他有用的输出可以由printf '%q\n' "$pod_in_question" 而不是echo 生成。
  • @paddy,你一直都是对的。 Hexdump 很高兴myapp-\E[m\E[K08wsz 来自 grep 的颜色。添加建议的选项已删除不需要的转义字符。请将您的评论作为答案,以便我接受。

标签: bash macos shell curl command-line


【解决方案1】:

一个强大的解决方案 - 基本的cURL CLI 调试。

在确定 OP 的问题与 curl 应用颜色输出有关后,此答案已修改。

有一个建议的答案清楚地解释了嵌入的特殊字符的含义,以及覆盖grep 行为以不输出颜色的说明。当然,这是 grep 在管道中使用的好习惯。然而,有许多最佳实践可以帮助诊断此问题或cURL 的类似问题,并最终导致最强大的解决方案。

重现问题

  1. 假设它是 JSON Content-Type,我们使用echo {'"name": "myapp-7414"'} 来模拟来自cURL 的输出
  2. 我们过滤文本并使用它设置一个变量,以便在cURL 命令中使用
  3. 我们强制grep 输出颜色,因为默认情况下它在输出到 tty 时通常不会。

    娱乐:

    myvar=$(echo {'"name": "myapp-7414"'} | grep --color=always -i '"name": "myapp-' | cut -d '"' -f 4)
    curl "https://www.google.com/${myvar}"
    

    输出:

    curl: (3) [<strong>globbing</strong>] bad range in column 32

首先: '{}'cURL 的特殊字符,句号。

  • cURL中的URL语法最佳实践:

    • 如果需要变量扩展:

      • 应用-g 开关以禁用cURL 完成的潜在通配
    • 否则:

      • 使用$variable 作为“引用”url 字符串的一部分,而不是${variable}

第二:除了-g,我们还添加了--libcurl /tmp/libcurl,这样我们就可以深入了解cURL看到的内容。

   -g--libcurl 一起娱乐:

  • curl -g --libcurl /tmp/libcurl  "https://www.google.com/${myvar}"

    输出:

    &lt;p&gt;Your client has issued a malformed or illegal request &lt;ins&gt;That’s all we know.

完美,至少现在一切都可以到达服务器并返回!让我们看看cURL 向服务器发送了什么:

cat /tmp/libcurl

我们确实找到了这一行:(注意粗体部分)。

curl_easy_setopt(hnd, CURLOPT_URL, "https://www.google.com/myapp-<strong>\033[m7414</strong>");

所以我们知道:

  1. shell 对我们的变量做了一些奇怪的事情。
  2. cURL 知道一旦我们发送 -g 开关就不要尝试 glob。这样 - 如果 shell 变量存在错误,我们实际上可以查看它是什么。如果我们不尝试使用 URL 范围,则不应调试通配错误。
  3. 特殊字符是颜色。它们代表我们为模拟 OP 环境而添加的 --color=always

此时。既然我们正在处理 JSON 数据,为什么不直接使用广泛可用的高性能 JSON 解析工具。这有很多好处,包括:

  • 不依赖任何可能影响字符串过滤的环境
  • 可以请求我们想要的数据(又名“名称”)
  • 应用名称“myapp”可以更改,我们无需重新编写代码来检索它。
  • 它更简洁,并且考虑了我尚未考虑的事情。

例如,如果我们使用jq(当我们使用它时,我们不需要-g 开关,因为我们不需要'{}'作为变量,因为我们已经是双倍@987654353 @网址):

myvar=$(echo {'"name": "myapp-7414"'} | jq -r .name)
curl --libcurl /tmp/libcurl "https://www.google.com/$myvar"

现在我们得到:

请求的 URL /myapp-7414 在此服务器上找不到。这就是我们所知道的。


太棒了。现在一切正常。应该很明显,这里的测试 URL www.google.com 显然不会知道是 myapp-7414 是。

所以我们已经离开了:

  • Globbing 错误范围,到:
  • 网址格式错误,发送至:
  • 在服务器上找不到 URL。

我们可以也按照其他地方的建议更改grep 输出并将其覆盖为--color=never(正如我所指出的:如果必须使用grep,则--color=never 是在管道字符串时将其用作最佳实践的好方法,句号。)。然而,考虑到由于字符串过滤而导致的可移植性问题,以及我们已经在一个可以可靠解析的板上传递结构化数据这一事实,如果可能的话,更强大的解决方案就是这样做。

【讨论】:

  • 好的,我现在明白你的意思了。如果我能接受两个答案,我会因为你付出了很多努力。我会避免使用第三方jq 工具来实现可移植性。它终止了 shell 脚本中的简单性。如果要编写需要额外依赖项的脚本,是时候使用更重的东西了。基本上基本工具“无论如何都必须工作”,或者我需要学习如何让它们在这种情况下工作。否则,它们的价值会大大降低。
  • @user3081519 是的 - 完全有效,我同意,我更喜欢便携式(比如......它将在我的带有busybox便携式的openwrt路由器上运行)。在一定程度上也取决于应用和实施。我的答案是那些从搜索结果中登陆的人,给他们一个可以遵循的过程,这可能有助于许多场景。为 cmets 干杯。
【解决方案2】:

您在最后一部分显示的替换看起来像是您注入的一个调用ANSI escape sequencesgrep 可能没有检测到非 TTY 输出并且正在着色。

在支持 ANSI 转义序列的终端上,您的特定代码可能不可见。代码^E[m^E[K 设置屏幕模式并清除当前行。这就是为什么你认为echo 命令证明你的数据是正确的。

您可以使用以下方法检查原始数据:

echo "$pod_in_question" | hexdump -C

您应该会看到其中还有其他字符,这些字符以前没有出现在您的终端中。当您将这些“不可见”代码放入 URL 时,curl 会尝试对其进行编码,然后在遇到控制字符 (ESC) 时失败。

解决方案是将参数 --color=never 添加到您的 grep 调用中,这将禁用着色。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 2020-11-26
    • 2019-03-22
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    相关资源
    最近更新 更多