为什么Bash会评估我存储在先前变量中的变量扩展?

时间:2015-07-26 20:51:36

标签: linux bash

我试图弄清楚为什么Bash似乎正在评估变量的变量扩展,其中我使用先前定义的变量使用变量扩展。也许这里还有别的东西,但它是什么,我无法理解。

我定义了$ LATEST_VERSION来接受最后一个' /'在$ LOCATION中,我将从$ LATEST_URL重定向到的URL。

目前,$ LATEST_VERSION被评估为以下内容:

  

v0.11.17

这是我正在执行的代码:

#!/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的臂v0.11.17com / syncthing / syncthing /释放/下载/ v0.11.17

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

  

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

我尝试了将所有字符串添加到echo -e之前,即

LATEST_VERSION=`echo -e ${LOCATION##*/}`
VERSION=`echo -e ${3:-$LATEST_VERSION}`

LATEST_VERSION=`basename $LOCATION`

他们都给了我意想不到的输出。我有什么东西可以在这里找到吗?

谢谢。

2 个答案:

答案 0 :(得分:4)

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

HTTP标头由回车/换行组合(CR LF)终止。

您的Perl正则表达式(/^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将光标向后移动:

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

答案 1 :(得分:2)

你可能在互联网上的数据中得到了CRLF行结尾,并且回车(CR)搞砸了。它们将打印位置移动到行的开头,而不会强制换行(LF或换行)。这就是为什么你在行的开头看到.tar.gz的原因。

如果您通过od -c等程序回显LATEST_VERSION的值,则最后会看到回车\r

您的下载网址来自:

DOWNLOAD_URL="https://github.com/syncthing/syncthing/release/download/${VERSION}/syncthing-${OS}-${ARCH}-${VERSION}.tar.gz"
echo "DOWNLOAD_URL: ${DOWNLOAD_URL}"

显示段,您会看到以下三个段重叠:

DOWNLOAD_URL: https://github.com/syncthing/syncthing/release/download/v0.11.17\r
/syncthing-linux-arm-v0.11.17\r
.tar.gz

导致观察到的输出:

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

要修复,您可以编辑回车(请参阅Bash手册中的parameter expansion):

LATEST_VERSION=${LATEST_VERSION/$'\r'/}