使用curl下载文件时,如何跟踪链接位置并将其用于输出文件名(事先不知道远程文件名)?
例如,如果点击下面的链接,你会下载一个名为“pythoncomplete.vim”的文件名。但是使用curl的-O和-L选项,文件名只是原始的远程名称,笨拙的“download_script.php?src_id = 10872。”
curl -O -L http://www.vim.org/scripts/download_script.php?src_id=10872
要下载具有正确文件名的文件,您必须提前知道该文件的名称:
curl -o pythoncomplete.vim -L http://www.vim.org/scripts/download_script.php?src_id=10872
如果您可以在不事先知道名称的情况下下载文件,那将是非常好的,如果没有,是否有另一种方法可以通过命令行快速下载重定向文件?
答案 0 :(得分:135)
远程端使用Content-Disposition标头发送文件名。
如果您指定--remote-header-name
/ -J
,卷曲7.21.2或更新会自动执行此操作。
curl -O -J -L $url
答案 1 :(得分:31)
如果您的最新版本为curl
(7.21.2或更高版本),请参阅@jmanning2k's answer。
我有curl
的旧版本(如雪豹附带的7.19.7),做两个请求:HEAD
从响应头获取文件名,然后是{GET
1}}:
url="http://www.vim.org/scripts/download_script.php?src_id=10872"
filename=$(curl -sI $url | grep -o -E 'filename=.*$' | sed -e 's/filename=//')
curl -o $filename -L $url
答案 2 :(得分:10)
我想评论jmanning2k的答案,但作为一个新用户我不能,所以我试图编辑他的帖子是允许但编辑被拒绝说它应该是评论。 叹息
无论如何,请将此视为对他的回答的评论。
这似乎仅在标题看起来像示例中的filename=pythoncomplete.vim
时才有效,但有些网站会发送一个看起来像filename*=UTF-8' 'filename.zip'
的标题,其中一个标题不会被curl 7.28.0识别
答案 3 :(得分:9)
如果您可以使用wget
代替curl
:
wget --content-disposition $url
答案 4 :(得分:6)
我想要一个适用于旧版和新版Mac的解决方案,David为Snow Leopard提供的遗留代码在Mavericks下表现不佳。这是我根据David的代码创建的函数:
function getUriFilename() {
header="$(curl -sI "$1" | tr -d '\r')"
filename="$(echo "$header" | grep -o -E 'filename=.*$')"
if [[ -n "$filename" ]]; then
echo "${filename#filename=}"
return
fi
filename="$(echo "$header" | grep -o -E 'Location:.*$')"
if [[ -n "$filename" ]]; then
basename "${filename#Location\:}"
return
fi
return 1
}
通过此定义,您可以运行:
url="http://www.vim.org/scripts/download_script.php?src_id=10872"
filename="$(getUriFilename $url)"
curl -L $url -o "$filename"
答案 5 :(得分:2)
请注意,某些配置错误的网络服务器将使用“文件名”作为密钥提供名称,其中RFC2183指定它应为“文件名”。 curl只处理后一种情况。
答案 6 :(得分:1)
使用上面的答案为Apache Archiva工件库提取最新版本的示例。 curl返回Location行,文件名位于行尾。需要删除文件名末尾的CR。
url="http://archiva:8080/restServices/archivaServices/searchService/artifact?g=com.imgur.backup&a=snapshot-s3-util&v=LATEST"
filename=$(curl --silent -sI -u user:password $url | grep Location | awk -F\/ '{print $NF}' | sed 's/\r$//')
curl --silent -o $filename -L -u user:password $url
答案 7 :(得分:0)
我有和约翰·库珀一样的问题。我没有文件名,但返回了位置文件名。他的回答也有用,但是有两个命令。 这个班轮为我工作。...
url="https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=de";url=$(curl -L --head -w '%{url_effective}' $url 2>/dev/null | tail -n1) ; curl -O $url
答案 8 :(得分:0)
使用建议的解决方案 above,我编写了这个辅助函数 curl2file
function curl2file() {
url=$1
url=$(curl -L --head -w '%{url_effective}' $url 2>/dev/null | tail -n1) ; curl -O $url
}
用法:
curl2file https://cloud.tsinghua.edu.cn/f/4666d28af98a4e63afb5/?dl=1