Curl 在以下位置后获取远程文件名

问题描述 投票:0回答:9

使用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

如果您可以在不提前知道文件名的情况下下载该文件,那就太好了,如果不能,是否有另一种方法可以通过命令行快速下载重定向的文件?

unix command-line curl
9个回答
183
投票

远程端使用 Content-Disposition 标头发送文件名。

如果您指定

--remote-header-name

 / 
-J
curl 7.21.2 或更高版本会自动执行此操作。

curl -O -J -L $url

参数的扩展版本将是:

curl --remote-name --remote-header-name --location $url

35
投票

如果您有最新版本的

curl
(7.21.2 或更高版本),请参阅 @jmanning2k 的回答

我有旧版本的

curl
(例如 Snow Leopard 附带的 7.19.7),请执行两个请求:一个
HEAD
从响应标头获取文件名,然后是一个
GET
:

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"

20
投票

如果您可以使用

wget
代替
curl
:

wget --content-disposition $url

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"

2
投票

请注意,某些配置错误的网络服务器将使用“文件名”作为键来提供名称,其中 RFC2183 指定它应该是“文件名”。 curl 只处理后一种情况。


2
投票

我和约翰·库珀有同样的问题。我没有得到文件名,但得到了位置文件名。他的回答也有效,但有两个命令。 这个单线对我有用......

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

窃取并添加了一些东西 https://unix.stackexchange.com/questions/126252/resolve-filename-from-a-remote-url-without-downloading-a-file


1
投票

使用上面的 Apache Archiva 工件存储库答案来提取最新版本的示例。卷曲返回位置行,文件名位于该行的末尾。需要删除文件名末尾的 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

1
投票

不是应用

grep
和其他 Unix-Fu 操作,
curl
附带专门针对这种情况的内置“写出”选项变量[1],例如

$ curl -OJsL "http://www.vim.org/scripts/download_script.php?src_id=10872" -w "%{filename_effective}"
pythoncomplete.vim

[1]https://everything.curl.dev/usingcurl/verbose/writeout#available-write-out-variables


0
投票

使用上面提出的解决方案,我编写了这个辅助函数curl2file.


[已更新]

function curl2file() { url=$1 url=$(curl -o /dev/null -L --head -w '%{url_effective}' $url 2>/dev/null | tail -n1) ; curl -O $url }
用途:

curl2file https://cloud.tsinghua.edu.cn/f/4666d28af98a4e63afb5/?dl=1
    
© www.soinside.com 2019 - 2024. All rights reserved.