bash变量展开中出现的奇怪字符
尝试在contos7上执行以下操作的效果与我预期的一样:bash变量展开中出现的奇怪字符,bash,macos,shell,curl,command-line,Bash,Macos,Shell,Curl,Command Line,尝试在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/a
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)上尝试同样的方法会产生:
卷曲:(3)[globbing]第92列中的错误范围
当我尝试使用-g
选项卷曲最后一行时,它将替换为格式错误的名称,例如:myapp-\\x1b[m\\x1b[Kl1eti\
echo语句总是执行得很好,并显示类似于myapp-v7454
的内容,稍后我想将其放入最后一个curl语句中。那么这些其他字符来自哪里呢?一个健壮的解决方案-Basiccurl
CLI调试。
在确定OP的问题与卷曲应用颜色输出有关后,对该答案进行了修订
有一个建议的答案,它清楚地解释了嵌入的特殊字符的含义,以及覆盖grep
行为以不输出颜色的说明。当然,这对于grep
在管道中的使用是一个很好的实践。然而,有许多最佳实践可以帮助诊断此问题或类似的问题<代码>卷曲并最终导致最强健的解决方案
重新创建问题
echo{''name:“myapp-7414”}
来模拟cURL
cURL
命令grep
输出颜色,因为在默认情况下,当输出到tty时,它不会输出颜色。
娱乐:
myvar=$(echo {'"name": "myapp-7414"'} | grep --color=always -i '"name": "myapp-' | cut -d '"' -f 4)
curl "https://www.google.com/${myvar}"
输出:
输出:
我们只知道您的客户发出了格式错误或非法的请求。
cURL
发送到服务器的内容:
cat /tmp/libcurl
我们当然可以找到这一行:(注意粗体部分)
现在我们得到:
在此服务器上找不到请求的URL/myapp-7414
。我们只知道这些
太好了。现在一切都正常了。很明显,这里的测试URL
www.google.com
显然不会知道是myapp-7414
是什么
因此,我们从:
- 全球化坏范围,到:
- 格式错误的URL,指向:
- 在服务器上找不到URL
我们也可以按照其他地方的建议,更改
grep
输出,并将其覆盖为--color=never
(正如我所指出的:如果必须使用grep
,则--color=never
是一种很好的方法,可以将其用作管柱、周期和管道连接时的最佳实践。)但是,考虑到由于字符串过滤已经遇到的可移植性问题,以及我们已经将结构化数据放在一个可以可靠解析的板上,如果可能的话,更可靠的解决方案就是这样做。您在最后一部分显示的替换看起来像是您的一个注入调用。这是po可能grep没有检测到非TTY输出,正在着色
在支持ANSI转义序列的终端上,您的特定代码可能不可见。代码^E[m^E[K
设置屏幕模式并清除当前行。这就是为什么您认为echo
命令证明您的数据是正确的
您可以使用以下方法检查原始数据:
echo "$pod_in_question" | hexdump -C
你应该看到还有其他一些字符以前没有出现在你的终端中。当你把这些“不可见”的代码放到URL中时,curl会尝试对它们进行编码,然后在遇到控制字符(ESC)时失败
解决方案是将参数
--color=never
添加到您的grep调用中,这将禁用着色功能。如果有更多的信息就好了,因为您的示例中没有一个是可重复的。Mac上的pod_in_question
的值是多少?可能存在字符编码问题。如果是,您可以翻译它是通过iconv实现的。但是,您在最后一部分显示的替换看起来像是您的一个注入调用。可能是grep没有检测到非TTY输出,正在着色。请尝试向grep添加--color=never
参数。@paddy更新了更多信息,您需要调试调用链。这些转义序列将设置屏幕取消并擦除该行。使用echo
将其输出到支持转义序列的终端将看起来很好。相反,为什么不使用echo“$pod\u in\u question”检查您的值| hextump-C
。我同意paddy的观点-hextump会提供大量信息。其他有用的输出可以通过printf“%q\n'”$pod\u in_question“
生成,而不是echo
@paddy,你一直都是对的。hextump狂欢myapp-\E[m\E[K08wsz
来自grep的着色。添加建议选项已删除不需要的转义字符。请将您的评论作为一个答案,以便我可以接受。好的,我现在明白您的意思。如果我可以接受两个答案,我会接受,因为您付出了大量的努力。仍然有一个第三方jq
可移植性工具非常重要我要避免的方法。它终止了shell脚本中的简单性。如果要编写需要额外依赖项的脚本,则是时候使用更重的方法了。基本的工具“无论如何都必须工作”或者我需要学习如何让它们在这种情况下工作。否则,它们的价值会显著降低。@user3081519是的-完全正确,我同意,我更喜欢便携设备(比如……它会在我的openwrt路由器上运行吗?busybox
portable)。在某种程度上也取决于应用程序和实现。我的答案适用于那些通过搜索登陆的用户
cat /tmp/libcurl
curl_easy_setopt(hnd, CURLOPT_URL, "https://www.google.com/myapp-\033[m7414");
myvar=$(echo {'"name": "myapp-7414"'} | jq -r .name)
curl --libcurl /tmp/libcurl "https://www.google.com/$myvar"
echo "$pod_in_question" | hexdump -C