저장소에서 최신 버전의 애플리케이션을 다운로드하고 애플리케이션을 배포하는 스크립트를 작성 중입니다.
주요 문제: 여러 저장소가 있으며 그 중 어느 저장소가 최신 버전인지 확인해야 합니다.
예를 들어
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
다음 옵션을 사용하십시오. -s
Silent Curl은 헤더 외에는 아무것도 인쇄하지 않습니다. -k
"안전하지 않은" SSL 연결을 허용합니다. 그렇지 않으면 컬이 자체 서명된 인증서를 거부합니다. -L
HTTP(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
-L
curl
리디렉션을 따르 겠습니다 .--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
요청합니다 . 사용 가능한 변수를 제공합니다.curl
man 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