Завиток, чтобы получить удаленное имя файла после следующего местоположения - PullRequest
69 голосов
/ 30 июля 2011

При загрузке файла с помощью curl, как бы я следовал по расположению ссылки и использовал его для выходного имени файла (не зная заранее имя удаленного имени файла)?

Например, если щелкнуть ссылку ниже, вы скачаете файл с именем «pythoncomplete.vim». Однако, используя параметры -O и -L curl, имя файла - это просто оригинальное имя удаленного сервера, неуклюжее «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

Было бы замечательно, если бы вы могли загрузить файл, не зная заранее его имени, и если нет, есть ли другой способ быстро вызвать перенаправленный файл через командную строку?

Ответы [ 7 ]

139 голосов
/ 13 января 2012

Удаленная сторона отправляет имя файла с помощью заголовка Content-Disposition.

curl 7.21.2 или новее делает это автоматически, если вы укажете --remote-header-name / -J.

curl -O -J -L $url
31 голосов
/ 30 июля 2011

Если у вас последняя версия curl (7.21.2 или новее), см. Ответ @ jmanning2k .

Если у вас более старая версия curl (например, 7.19.7, поставляемая вместе со Snow Leopard), выполните два запроса: 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
11 голосов
/ 27 января 2018

Если вы можете использовать wget вместо curl:

wget --content-disposition $url
10 голосов
/ 24 октября 2012

Я хотел прокомментировать ответ jmanning2k, но как новый пользователь я не могу, поэтому я попытался отредактировать его сообщение, которое разрешено, но редактирование было отклонено, сказав, что это должен быть комментарий. вздох

В любом случае, смотрите это как комментарий к его ответу спасибо.

Это работает, только если заголовок выглядит как filename=pythoncomplete.vim, как в примере, нонекоторые сайты отправляют заголовок, который выглядит как filename*=UTF-8' 'filename.zip', который не распознается curl 7.28.0

6 голосов
/ 22 октября 2014

Мне нужно было решение, которое работало бы как на старых, так и на новых компьютерах Mac, а устаревший код, предоставленный Дэвидом для Snow Leopard, не очень хорошо работал при Mavericks.Вот функция, которую я создал на основе кода Дэвида:

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 голосов
/ 04 июня 2014

Обратите внимание, что некоторые неправильно настроенные веб-серверы будут использовать имя, используя «Filename» в качестве ключа, где RFC2183 указывает, что это должно быть «filename».curl обрабатывает только последний случай.

1 голос
/ 20 февраля 2015

Пример использования ответа выше для хранилища артефактов 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...