首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Bash评估我存储在前一个变量中的变量展开?

为什么Bash评估我存储在前一个变量中的变量展开?
EN

Stack Overflow用户
提问于 2015-07-26 20:51:36
回答 2查看 49关注 0票数 1

我试图弄清楚为什么Bash似乎在为一个变量计算变量展开,在这个变量中,我使用了以前定义的变量,即使用变量展开。也许这里还有别的事情要发生,但我不太清楚到底是什么。

我将$LATEST_VERSION定义为将$LOCATION中的最后一个'/‘之后的所有内容,也就是从$LATEST_URL重定向到的URL。

目前,对$LATEST_VERSION的评估如下:

v0.11.17

这是我正在执行的代码:

代码语言:javascript
复制
#!/bin/bash
OS=${1:-"linux"}
ARCH=${2:-"arm"}
LATEST_URL="https://github.com/syncthing/syncthing/releases/latest"
LOCATION=`curl -I $LATEST_URL | perl -n -e '/^Location: (.*)$/ &&  print "$1\n"'`
LATEST_VERSION=${LOCATION##*/}
VERSION=${3:-$LATEST_VERSION}
DOWNLOAD_URL="https://github.com/syncthing/syncthing/release/download/${VERSION}/syncthing-${OS}-${ARCH}-${VERSION}.tar.gz"
echo "DOWNLOAD_URL: ${DOWNLOAD_URL}"

一切都很好,直到我echo "DOWNLOAD_URL: ${DOWNLOAD_URL}"

.tar.gzing-linux-arm-v0.11.17com/syncthing/syncthing/release/download/v0.11.17

如果我从$VERSION中取出$DOWNLOAD_URL,它看起来就像预期的那样($OS和$ARCH被替换了):

DOWNLOAD_URL:https://github.com/syncthing/syncthing/release/download//syncthing-linux-arm-.tar.gz

我尝试了所有的方法,从用echo -e对字符串进行前缀,即

代码语言:javascript
复制
LATEST_VERSION=`echo -e ${LOCATION##*/}`
VERSION=`echo -e ${3:-$LATEST_VERSION}`

代码语言:javascript
复制
LATEST_VERSION=`basename $LOCATION`

它们都给了我意想不到的结果。这里有什么我遗漏的东西吗?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-26 20:59:33

有一个特殊的字符称为回车(ASCII 13,也称为CR或\r),它在打印时将光标移动到行的开头。

HTTP报头被回车/行提要组合(CR )终止。

您的Perl regex (/^Location: (.*)$/)删除LF (默认情况下.不匹配换行符),但保留CR。

最后,LATEST_VERSION包含v0.11.17\r ( \r表示不可见的回车)。

DOWNLOAD_URL最后是https://github.com/syncthing/syncthing/release/download/v0.11.17\r/syncthing-linux-arm-v0.11.17\r.tar.gz (再次使用\r来表示回车),当打印出来时,因为\r将光标移回,所以看起来很混乱:

代码语言:javascript
复制
https://github.com/syncthing/syncthing/release/download/v0.11.17
/syncthing-linux-arm-v0.11.17
.tar.gz
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tar.gzing-linux-arm-v0.11.17syncthing/release/download/v0.11.17

解决这一问题的一种方法是将正则表达式更改为/^Location: (.*)\r\n/,这会将\r移出$1

票数 4
EN

Stack Overflow用户

发布于 2015-07-26 20:59:01

你可能已经在互联网上的数据中找到了CRLF线路的结尾,而回车(CR)正在把事情搞砸。它们将打印位置移动到行的开头,而不强制输出换行符(LF或行提要)。这就是为什么你在这条线的开头看到.tar.gz

如果您通过像LATEST_VERSION这样的程序来回显od -c的值,您将在最后看到回车\r

您的下载URL创建于:

代码语言:javascript
复制
DOWNLOAD_URL="https://github.com/syncthing/syncthing/release/download/${VERSION}/syncthing-${OS}-${ARCH}-${VERSION}.tar.gz"
echo "DOWNLOAD_URL: ${DOWNLOAD_URL}"

显示这些段时,您将看到以下三个覆盖段:

代码语言:javascript
复制
DOWNLOAD_URL: https://github.com/syncthing/syncthing/release/download/v0.11.17\r
/syncthing-linux-arm-v0.11.17\r
.tar.gz

导致观察到的产出:

代码语言:javascript
复制
.tar.gzing-linux-arm-v0.11.17com/syncthing/syncthing/release/download/v0.11.17

要修复,您可以编辑回车(参见Bash手册中的参数展开 ):

代码语言:javascript
复制
LATEST_VERSION=${LATEST_VERSION/$'\r'/}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31641821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档