我正在编写一个 shell 脚本来下载某些软件的最新版本。在我解析输出后,curl
我通过几个步骤来找到确切的版本字符串(在写这篇文章的时候是0.65.3
):
(在下面的所有代码示例中,>
都是我的提示。来自 Bash 3.2 或 Zsh 的输出位于没有>
前缀的行上。)
> url="https://github.com/gohugoio/hugo/releases/latest"
> latest=$(curl --silent --head "$url" | grep Location)
> tag=$(echo "$latest" | cut -d'/' -f8)
> version=$(echo "${tag//v}")
> echo "hugo_${version}_Linux-64bit.tar.gz"
_Linux-64bit.tar.gz
我期望的输出是hugo_0.65.3_Linux-64bit.tar.gz
,但是在使用带引号的字符串的调用的输出中,echo
似乎后面的字节${version}
已用于覆盖带引号的字符串开头的字节。
在这里,我使用两个不同的引用字符串来澄清正在发生的事情:
> echo "hugo_${version}test"
test_0.65.3
> echo "hugo_${version}lorem ipsum dolor sit amet"
lorem ipsum dolor sit amet
如果我这样做,我会得到同样的意外结果:
> version=$(echo "${tag:1}")
> echo "hugo_${version}_Linux-64bit.tar.gz"
_Linux-64bit.tar.gz
但是,如果我这样做,我会得到预期的结果:
> version=0.65.3
hugo_0.65.3_Linux-64bit.tar.gz
最后一个结果是必需的,但当然它使我的脚本是静态的而不是动态的,因此对我来说不是很有用。如何在不硬编码$version
脚本中的值的情况下获得所需的结果?
返回的行
curl
以回车换行结束。(MS-dos 行结尾)。Unix 工具会删除换行符,但最后会留下回车符。修复此行以使用
dos2unix
(并引用您的论点echo
,避免BashPitfalls #14中描述的错误):...或者,使用 shell 的内置语法同时执行两个更改:
dos2unix
确实进行了一些其他更改(例如在文本的最后一行之后添加尾随换行符,UNIX 需要,但 DOS 不需要),但对于像这样的单行字符串,它们都不重要。ctrl-alt-delor的回答解释了为什么你会看到这种行为;但为了解决您的基本目标,我建议使用GitHub API而不是解释“最新”重定向:
这会向 API 询问最新 Hugo 版本的信息,并使用 提取标签名称
jq
,去除任何前导的“v”。理想情况下,您甚至可以从返回的 JSON 中提取资产名称和 URL。