二重引用符で囲まれた文字列で、変数拡張後のバイトが前のバイトを上書きするのはなぜですか?

二重引用符で囲まれた文字列で、変数拡張後のバイトが前のバイトを上書きするのはなぜですか?

一部のソフトウェアの最新バージョンをダウンロードするためのシェルスクリプトを作成しています。出力を解析した後、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}列の先頭にあるバイトを上書きするために使用されているようです。

ここでは、何が起こっているかを説明するために、2つの異なる引用文字列を使用しています。

> 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スクリプトの値をハードコーディングせずに、どのような結果を得ることができますか?

ベストアンサー1

返された行はcurlキャリッジリターンと改行で終わります。 (MS-dos 行末)。 Unixツールは改行文字を削除しますが、最後にキャリッジリターンが残ります。

次のエラーを回避するには、この行を修正して使用し、dos2unixパラメータをとして引用します。echoバッシュトラップ #14):

version="$(echo "${tag//v}" | dos2unix)"

...またはシェルの組み込み構文を使用して実行します。両方今変更:

version=${tag//[$'v\r']/}

dos2unix実際には、いくつかの異なる変更が適用されました(たとえば、UNIXでは必要ですがDOSでは不要なテキストの最後の行の後に末尾の改行を追加するなど)。しかし、このような単一行文字列の場合、これらの変更のどれも重要ではありません。

おすすめ記事