自動跳轉的下載地址,用 curl 下載怎樣保留原檔名?
自動跳轉的下載地址,用 curl 下載怎樣保留原檔名?
本文已參與「新人創作禮」活動,一起開啟掘金創作之路。
最近在寫 Jenkinsfile
的時候遇到了一個場景,需要從一條連結地址下載 jar
包,jar 包名字是帶版本號的,我是希望不改變原來檔名的情況下去下載到某個目錄下。
一開始覺得這個場景需求不難哦,首先想到的是用我比較熟的 curl
命令直接下載就應該就可以了,馬上開工!
第一次失敗
我們這次要下載的連結長這樣(用 log4j-api
的倉庫地址舉例):
sh
https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST
先用瀏覽器開啟一下連結,看看能不能正常下載:
沒有問題,而且自動下載了最新版本的 jar 包,名字叫 log4j-api-2.14.1.jar
,完美的很,現在馬上轉戰 curl 命令。
ssh
$ curl -O https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST
這個大寫的 -O
引數表示不需要指定檔名,用連結的檔名字來作為檔名。
一個回車下去,問題來了:
出現了很多奇奇怪怪的東西,而且下載下來的檔名變成了 'redirect?r=central-proxy'
。
我們來 cat
一下這個檔案看看裡面有什麼線索:
原來是返回了一個 400 - Bad Request
的頁面,看來是我們的地址有點問題,我們一起來仔細看看這條地址,其實可以看到地址後面有好幾個引數:
r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST
可以看到裡面帶了個 &
符號,這個符號在 Linux 裡是指後臺執行,所以我們的地址還不能直接用。
知識點一:
這裡可以有兩種方法解決問題:
- 轉義 url,將
&
前增加反斜槓\&
。- 用
curl -d
引數來傳參,並且強制使用GET
方法-G
。```sh
方法一:轉義 url
$ curl -O https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy\&g=org.apache.logging.log4j\&a=log4j-api\&v=LATEST
方法二:用 curl -d 引數
$ curl -O -G \ https://repository.sonatype.org/service/local/artifact/maven/redirect \ -d "r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST" ```
小插播:
歡迎關注我的 VX 號:
叨叨技術 (daodao_tech)
前沿技術,深度評測
原創文章,首發公眾
第二次失敗
通過上面兩個方法我們又下載了一個東西:
從截圖可以看到,我們下載下來的檔名還是不太對,叫做 'redirect?r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST'
,並不是我們想要的 log4j-api-2.14.1.jar
。
我們繼續 cat
一下它:
這次檔案裡面的內容不一樣了,裡面返回了一段話:
text
If you are not automatically redirected use this url: https://repository.sonatype.org/service/local/repositories/central-proxy/content/org/apache/logging/log4j/log4j-api/2.14.1/log4j-api-2.14.1.jar
蕪湖,起碼伺服器正確返回了我們想要的下載地址,但是為什麼我們還是下載不到呢?
知識點二:
從內容可以猜測,伺服器其實是想重定向到裡面真正的下載地址讓我們下載,我們可以通過引數
curl -i
來列印HTTP
的頭來看看:
從截圖可以看到,伺服器返回了 HTTP 307
的狀態碼,而且 Header
裡面有 location
的引數,所以證實了我們的想法,那怎麼讓 curl
去自動重定向到伺服器返回的地址呢?
知識點三:
這裡我們可以通過用
curl -L
引數來解決問題,-L
引數表示Follow redirects
,就是說告訴 curl 自動重定向到新的連結。
第三次失敗
感覺要解決這個問題了!我們馬上試下:
sh
$ curl -O -L https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy\&g=org.apache.logging.log4j\&a=log4j-api\&v=LATEST
啊哈,好像成功下載到東西了!從截圖可以看到它下載了 293k
的東西,跟我們從瀏覽器下載的大小一樣。
但是!為啥檔名還是不對呢,並不是我們想要的 log4j-api-2.14.1.jar
。
知識點四:
雖然我們用了
curl -L
引數實現了自動重定向到下載連結,但是curl -O
引數只會用到最開始的地址作為下載的檔名。
第四次嘗試
既然不能直接 curl -O
,那有沒有辦法先拿到真正的下載地址,再用 curl -O
去請求地址,那不是可以保留原檔名下載了嗎?
先上命令程式碼:
sh
$ curl -I -L -s https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy\&g=org.apache.logging.log4j\&a=log4j-api\&v=LATEST \
-o /dev/null \
-w %{url_effective}
知識點五: 這個命令裡面有很多知識點要介紹下:
curl -I
引數表示只打印資訊,不會真正下載curl -s
(小寫)引數表示靜默模式curl -o /dev/null
(小寫)表示將輸出的東西重定向到/dev/null
丟棄curl -w %{url_effective}
(小寫)表示輸出最後的url
地址
所以通過上面的命令,我們能夠獲取到最後的下載地址了:
第五次成功
既然我們都獲取到真正的下載地址了,那麼我們拿著這個地址再用 curl -O
就可以達到我們想要的效果了。
立刻上程式碼:
sh
$ curl -I -L -s https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy\&g=org.apache.logging.log4j\&a=log4j-api\&v=LATEST \
-o /dev/null \
-w %{url_effective} \
| xargs curl -O
終於成功! 我們再優化一下上面的命令,可以得到最後我們要的命令程式碼:
sh
$ curl -GILs https://repository.sonatype.org/service/local/artifact/maven/redirect \
-d "r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST" \
-o /dev/null \
-w %{url_effective} \
| xargs curl -O
最後
歡迎關注我的 VX 號:叨叨技術 (daodao_tech)
前沿技術,深度評測
原創文章,首發公眾