파일을 다운로드하지 않고 원격 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:서버의 30x HTTP 응답에서 헤더를 찾으세요.
  • tail -n1마지막 것을 선택하세요
  • cut -d' ' -f2두 번째 필드(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

관련 정보