一部のソフトウェアの最新バージョンをダウンロードするためのシェルスクリプトを書いています。 curl
の出力を解析した後、正確なバージョン文字列を見つけるためにいくつかのステップを実行します(これを書いている時点では0.65.3
です):
(以下のすべてのコードサンプルで、>
は私のプロンプトです。Bash3.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
これを実行すると、同じnexpected結果が得られます。
> version=$(echo "${tag:1}")
> echo "hugo_${version}_Linux-64bit.tar.gz"
_Linux-64bit.tar.gz
しかし、これを行うとexpectedの結果が得られます。
> version=0.65.3
hugo_0.65.3_Linux-64bit.tar.gz
この最後の結果が必要なものですが、もちろん、スクリプトが動的ではなく静的になるため、あまり役に立ちません。スクリプトで$version
の値をハードコーディングせずに、目的の結果を得るにはどうすればよいですか?
curl
によって返される行は、改行で終了します。 (MS-dos行末)。改行はUnixツールによって削除されますが、最後に改行が残ります。
dos2unix
を使用するようにこの行を修正します(そしてecho
への引数を引用符で囲み、 BashPitfalls#14 で説明されているバグを回避します):
version="$(echo "${tag//v}" | dos2unix)"
...または、シェルの組み込み構文を使用してboth変更を一度に実行します。
version=${tag//[$'v\r']/}
dos2unix
は他の変更をいくつか行います(UNIXで必要なテキストの最後の行の後に末尾の改行を追加するなど)。ただし、このような1行の文字列ではそれらのどれも重要ではありません。
ctrl-alt-delor の answer は、この動作が見られる理由を説明しています。ただし、根本的な目標に対処するには、「最新の」リダイレクトを解釈する代わりに、 GitHub API を使用することをお勧めします。
version=$(curl https://api.github.com/repos/gohugoio/hugo/releases/latest | jq -r '.tag_name | ltrimstr("v")')
これはAPIに最新のHugoリリースの情報を要求し、 jq
を使用してタグ名を抽出し、先行する「v」を削除します。
理想的には、返されたJSONからアセット名とURLを抽出することもできます。