问题描述
原本,是想写一个脚本来从 Unsplash 下载图片,通过 apt install axel
安装了 axel
来进行下载(相对较快);使用 jq
来对返回的 json 进行解析,获取下载地址,为了测试命令的有效性,将返回的 json 结果存放在文件中 unsplash.json 中 :
1 | [ |
调用 jq
命令解析,并将 download
的值作为 axel
的命令行参数:
1 | jq -C .[].links.download unsplash.json | xargs -t -n 1 axel -o 2.jpg |
标准输出或者错误显示不能解析 URL, 查看这个 URL 没有问题,直接执行 axel -o 2.jpg https://unsplash.com/photos/3AzS4zAYaXk/download
也没有出现异常。 由于没有显示具体的 URL 异常在哪里,换用 cUrl
来执行:
1 | jq -C .[].links.download unsplash.json | xargs -t -n 1 curl -o 2.jpg |
同样,请求失败,同样直接执行 curl -o 2.jpg https://unsplash.com/photos/3AzS4zAYaXk/download
也能够成功,显然通过 jq
输出,再通过管道符和 xargs
输出的 url 不正常,但是直接看有没有什么特殊的字符,期间,尝试将 jq
解析的结果保存成变量,url 中添加变量,如:
1 | curl -o 2.jpg $varUrl |
同样执行失败,百思不得其解 :laughing: .
解决思路
智商不够,百度来凑,无果,打开 StackOverFlow, 搜索 bad range in column
,从一个类似的问题中找到了线索或者说答案。
原文 strange-characters-appearing-in-bash-variable-expansion) 中描述的问题是通过 grep
命令 filter json 中的值,并将其作为变量,在 curl 的 url 中引用该变量:
1 | pod_in_question=$(curl -u uname:password -k very.cluster.com/api/v1/namespaces/default/pods/ | grep -i '"name": "myapp-' | cut -d '"' -f 4) |
结果,请求 url 中出现一些特殊的转义字符,原因是使用的 bash 环境, grep
命令默认使用 --colour=always
, 使得过滤的结果中出现了颜色的转义序列 ANSI escape sequences, 支持这些转义序列的终端的这些字符不可见,使用 hexdump -C
可以查看,因此针对原文的问题解决方案就是 grep --colour=never
.
再回到我的问题,使用 hexdump 打印:
1 | jq -C .[].links.download unsplash.json | hexdump -C |
明显可以看到 url 的首尾出现了特殊的颜色转义字符,32 是绿色的色彩码. 显然, 是由于 jq -C
的选项造成的结果, 去掉或者指定 -M
(monochrome (don’t colorize JSON)), 问题解决了.
stackoverflow 中的问题还有一个答案, 给出了如何找出 cUrl
使用中出现问题如何定位的思路:
1 | jq -C .[].links.download unsplash.json | xargs -t -n 1 curl -g --libcurl /tmp/libcurl -o 2.jpg |
结论
引用 stackoverflow 给出使用
cURL
的最佳实践:The best practise for URL syntax in
cURL
:- If Variable Expansion is required:
- Apply the
-g
switch to disable potential globbing done bycURL
- Apply the
- Otherwise:
- Use
$variable
as part of a “quoted” url string, instead of${variable}
- Use
- If Variable Expansion is required:
使用
grep
,jq
以及管道符|
应该注意颜色转义序列, 为了使脚本通用, 必要时在所有可能会产生此类问题的命令中关闭颜色输出