自动跳转到下载地址,curl下载时如何保持原文件名?最近在写Jenkinsfile的时候,遇到一个场景,需要从一个链接地址下载一个jar包。jar包的名称带有版本号。希望在不改变原文件名的情况下,下载到某个目录下。一开始觉得这个场景的要求并不难。我最先想到的是可以用我熟悉的curl命令直接下载,应该可以的。立即开始工作!第一次失败,我们要下载的链接是这样的(以log4j-api仓库地址为例):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命令。$curl-Ohttps://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST这个大写的-O参数表示No需要指定文件名,使用链接文件名作为文件名。回车后,问题来了:出现了很多奇怪的东西,下载的文件名变成了'redirect?r=central-proxy'。我们cat一下这个文件,看看有什么线索:原来是返回了一个400-BadRequest页面。我们的地址好像有问题。让我们仔细看看这个地址。其实看地址后面就可以了。有几个参数:r=central-proxy&g=org.apache.logging.log4j&a=log4j-api&v=LATEST可以看到里面有个&符号。这个符号指的是在Linux中后台运行,所以我们的地址不能直接使用。知识点1:解决问题的方法有两种:对url进行转义,在&前加一个反斜杠\&。使用curl-d参数传递参数,强制使用GET方法-G。#方法一:转义url$curl-Ohttps://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吧:这次文件里的内容不一样了,里面返回了一段:如果没有自动重定向使用这个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芜湖,至少服务器正确返回了我们要的下载地址,但为什么还是可以下载呢呢子呢?知识点2:从内容可以猜到,服务器其实是要重定向到里面的真实下载地址,供我们下载。我们可以使用参数curl-i打印HTTPheader看看:从截图中可以看到,服务器返回了HTTP307的状态码,并且Header中有一个location参数,所以印证了我们的想法,那么如何让curl自动重定向到服务器返回的地址呢?知识点3:这里我们可以使用curl-L参数来解决问题。-L参数表示Followredirects,意思是告诉curl自动重定向到一个新的链接。第三次失败感觉是时候解决这个问题了!让我们马上尝试一下:$curl-O-Lhttps://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。知识点4:虽然我们使用curl-L参数自动重定向到下载链接,但是curl-O参数只会使用初始地址作为下载的文件名。由于第四次尝试不能直接curl-O,有没有办法先获取真实的下载地址,然后用curl-O请求地址,不就可以保留原文件名下载吗?第一个命令代码:$curl-I-L-shttps://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}知识点5:这个命令要介绍的知识点很多:curl-I参数表示只打印信息,将不实际下载curl-s(小写)参数表示静默模式curl-o/dev/null(小写)表示将输出重定向到/dev/nulldiscardcurl-w%{url_effective}(小写)表示输出最终的url地址所以通过上面的命令,我们可以得到最终的下载地址:第五次成功现在我们已经得到了真正的下载地址,那么我们就可以使用这个地址,使用curl-O来达到我们想要的效果。马上上传代码:$curl-I-L-shttps://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}\|xargscurl-O终于成功了!让我们再次优化上面的命令,得到我们想要的最终命令代码:apache.logging.log4j&a=log4j-api&v=LATEST"\-o/dev/null\-w%{url_effective}\|xargscurl-O最后,欢迎关注我的VX号:daodao_tech前沿技术,深度测评原创文章,首发公众号
