ファイルをダウンロードせずにリモートURLからファイル名を解析します。

ファイルをダウンロードせずにリモートURLからファイル名を解析します。

リポジトリから最新バージョンのアプリケーションをダウンロードし、アプリケーションをデプロイするスクリプトを作成しています。

主な問題:複数のリポジトリがあり、そのリポジトリが最新バージョンであることを確認する必要があります。

例えば

http://repo1/xyz/LATEST -> (redirects to) -> http://repo1/xyz/app-1.0.0.0.zip
http://repo2/xyz/LATEST -> (redirects to) -> http://repo1/xyz/app-1.1.0.0.zip

したがって、利用可能なリポジトリを繰り返してファイル名のみを取得する必要があります。古いバージョンのソフトウェアをダウンロードする必要はありません。

答え1

次のようなものが役に立ちます。

curl -sIkL http://repo1/xyz/LATEST | sed -r '/filename=/!d;s/.*filename=(.*)$/\1/'

curl(1)オプションについてはマニュアルページを確認してください。興味深いことに-I, --head

コメントで要求された説明:

アイデアは、HTTP応答ヘッダーのみを要求することです。

したがって、-I次のオプションを使用してください。-sSilent Curlはヘッダ以外には何も印刷しません。-k「安全でない」SSL接続を許可します。それ以外の場合、カールは自己署名証明書を拒否します。-LHTTP(S)位置リダイレクトに従います。

その後、sed(1)応答ヘッダーからファイル名を取得するために使用されます。このフィールドは検索中なので、filename=この/filename=/!dセクションではそのフィールドを持たない出力からすべての項目を削除します。最後に、s/.*filename=(.*)$/\1/ウィジェットはそのフィールドが見つかった場合にのみファイル名を印刷します。

答え2

@FloHimselfのソリューションと非常によく似たこのソリューションを思いつきました。

curl -L --head http://repo1/xyz/LATEST 2>/dev/null | grep Location: | tail -n1 | cut -d' ' -f2
  • -Lcurlリダイレクトに従ってください。
  • --headページの内容ではなくタイトルのみをインポートするようにしてください。
  • grep Location:Location:サーバーの30倍のHTTP応答でヘッダーを見つけます。
  • tail -n1最後のものを選択してください
  • cut -d' ' -f22番目のフィールド(URL)を選択してください。

同じですが、curlすべて完了してみましょう。

curl -L --head -w '%{url_effective}' http://repo1/xyz/LATEST  2>/dev/null | tail -n1

ソリューションはオプションを使用して特定の出力を-w, --write-out要求します。利用可能な変数を提供します。curlman curl

答え3

@lgeorgetが提供した答えは非常に似ていますが、それでも理想的ではありません。より良い解決策はfilename_effective変数を使用することです--write-out。ファイルをダウンロードしないと機能しないため、これは完全に理想的なものではありません。次のトピックでも言及されていますman curl

filename_effective
   The ultimate filename that curl  writes  out  to.
   This  is only meaningful if curl is told to write
   to a file with the --remote-name or --output  op‐
   tion.  It's  most  useful in combination with the
   --remote-header-name option.

ただし、ファイルが現在のフォルダに既に存在する場合はエラーが発生し、ダウンロードしたファイルは削除されます。 (対話型モードでは上書きするかどうかを尋ねるメッセージが表示されますが、非対話型モードでは、つまりスクリプトではエラーが発生します。エラー):

curl --remote-name \
     --remote-header-name \
     --location \
     --write-out '%{filename_effective}' \
     "${URL}"

したがって、スクリプトでこれを使用するには、次のようにします。

# just an example URL which will download Bitwarden's CLI software
URL='https://vault.bitwarden.com/download/?app=cli&platform=linux'

TMP_DOWNLOAD_RESULT="$(curl --remote-name \
                            --remote-header-name \
                            --location \
                            --write-out '%{exitcode};%{errormsg};%{filename_effective}' \
                            "${URL}")"

## break the result into its sub-parts
TMP_EXIT_CODE="$(echo "${TMP_DOWNLOAD_RESULT}" | cut -d ';' -f 1)"
TMP_EXIT_MESSAGE="$(echo "${TMP_DOWNLOAD_RESULT}" | cut -d ';' -f 2)"
TMP_REMOTE_FILE_NAME="$(echo "${TMP_DOWNLOAD_RESULT}" | cut -d ';' -f 3)"

# generate error or message of curl has failed.
if [ "${TMP_EXIT_CODE}" != "0" ]; then
    echo
    if [ "${TMP_EXIT_CODE}" == "23" ]; then
        echo "The local version is already the latest version."
        exit 0
    else
        echo "Downloading with cURL resulted in error number ${TMP_EXIT_CODE} with the message: \n\t${TMP_EXIT_MESSAGE}"
        exit 1
    fi
fi

関連情報