LinuxRuLinux без лишней теории
Сеть и загрузки

curl и wget в Linux: скачивание файлов, запросы к API и примеры

Редакция LinuxRu7 мин чтенияИнструкции

Скачать файл проще всего командой wget URL, а в curl нужно curl -LO URL: без -L он не пойдёт по редиректу. Для API берите curl: POST-запрос с JSON отправляет curl --json '{...}' URL. Ниже примеры докачки, заголовков, прокси и ключей для скриптов.

curl и wget в Linux: скачивание файлов, запросы к API и примеры
Фото: ProjectManhattan, CC BY-SA 3.0, Wikimedia Commons
Содержание
  1. curl или wget
  2. Скачать файл
  3. Докачка
  4. Заголовки
  5. POST и API
  6. Прокси
  7. curl в скриптах
  8. Ошибки
  9. Частые вопросы

curl или wget: что выбрать

wget создан для скачивания: дал ссылку, получил файл на диске, при обрыве продолжил. curl создан для запросов: он по умолчанию печатает ответ в терминал, зато умеет любые методы, заголовки и форматы тела. Для загрузки ISO-образа удобнее wget, для работы с REST API и отладки веб-сервера нужен curl.

Задачаwgetcurl
Скачать файлwget URLcurl -LO URL
Сохранить под своим именемwget -O имя URLcurl -Lo имя URL
Докачатьwget -c URLcurl -C - -LO URL
Ограничить скорость--limit-rate=2m--limit-rate 2M
Только заголовкиwget -S --spider URLcurl -I URL
POST с данными--post-data='a=1'-d 'a=1'
JSON в APIнеудобно--json '{...}'
Скачать сайт рекурсивноwget -m -k -p URLнет
Список URL из файлаwget -i list.txtxargs -n1 curl -LO < list.txt
ПротоколыHTTP(S), FTP (кроме wget2)HTTP(S), FTP, SFTP, SMB и другие

Обе утилиты есть в репозиториях всех дистрибутивов. curl обычно уже установлен; wget в минимальных образах и контейнерах бывает не установлен.

# Debian 13, Ubuntu 26.04, Mint
sudo apt install curl wget
# Fedora 44
sudo dnf install curl wget
# Arch
sudo pacman -S curl wget

В Fedora с 40-й версии команда wget предоставляется пакетом wget2-wget, то есть это Wget2. Для обычных загрузок разницы нет, но FTP и формат WARC wget2 не поддерживает, а вывод отличается, так что скрипты, которые разбирают текст прогресса, могут сломаться. Проверить, что стоит, можно через wget --version. Версии curl на октябрь 2026: 8.14.1 в Debian 13, ветка 8.2x в Arch и других rolling-дистрибутивах.

Как скачать файл через wget и curl

# wget сохранит файл под именем из URL
wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS
# в нужный каталог
wget -P ~/Загрузки https://example.org/file.tar.gz
# под своим именем
wget -O app.tar.gz "https://example.org/download?id=42"
# curl: -O берёт имя из URL, -L идёт по редиректам
curl -LO https://example.org/file.tar.gz
# имя из заголовка Content-Disposition (для ссылок вида download?id=)
curl -LOJ "https://example.org/download?id=42"
# без прогресса, но с ошибками
curl -fsSL -o app.tar.gz https://example.org/file.tar.gz

Самая частая ловушка curl: без -L он не следует за редиректом и сохраняет вместо файла маленькую HTML-страницу с текстом "Moved". Если скачанный архив весит пару сотен байт и не распаковывается, добавьте -L. Адреса с ? и & всегда берите в кавычки, иначе оболочка поймёт & как запуск в фоне.

После загрузки образа или архива сверьте контрольную сумму с опубликованной на сайте проекта:

sha256sum debian-*-amd64-netinst.iso
grep netinst SHA256SUMS

Как распаковать скачанное, разобрано в статье про архивы tar и zip.

Докачка, повторы и ограничение скорости

На плохой связи или при загрузке больших файлов пригодятся докачка и автоматические повторы:

# wget: продолжить с места обрыва
wget -c https://example.org/big.iso
# 20 попыток, пауза между ними, таймаут чтения
wget -c --tries=20 --waitretry=10 --read-timeout=30 https://example.org/big.iso
# в фоне, лог в wget-log
wget -b -c https://example.org/big.iso
tail -f wget-log
# список ссылок из файла, не больше 2 МБ/с
wget -c --limit-rate=2m -i urls.txt
# curl: докачка, -C - сам определяет смещение
curl -C - -LO https://example.org/big.iso
# повторы при любых ошибках
curl --retry 10 --retry-delay 5 --retry-all-errors -C - -LO https://example.org/big.iso
# параллельная загрузка нескольких файлов
curl -Z -LO https://example.org/a.iso -LO https://example.org/b.iso

Докачка работает, только если сервер поддерживает запросы диапазонов (заголовок Accept-Ranges: bytes). Если его нет, файл скачается заново с начала. Проверить заранее: curl -sI URL | grep -i accept-ranges.

Большие загрузки по SSH на сервере запускайте внутри tmux или через wget -b: при обрыве сессии процесс не умрёт, а -c позволит продолжить, даже если он всё же упал.

Заголовки, коды ответа и отладка

curl - основной инструмент, чтобы понять, что отвечает сервер: какие заголовки, куда редирект, работает ли сертификат.

# только заголовки ответа (метод HEAD)
curl -I https://example.org
# заголовки и тело вместе
curl -i https://example.org/api/status
# полный обмен, включая TLS и заголовки запроса
curl -v https://example.org -o /dev/null
# только код ответа и время
curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://example.org
# свой заголовок и User-Agent
curl -H 'Accept-Language: ru' -A 'Mozilla/5.0' https://example.org
# запрос к конкретному IP с нужным доменом (проверка до смены DNS)
curl --resolve example.org:443:203.0.113.10 -I https://example.org
# сохранить и отправить cookies
curl -c cookies.txt -b cookies.txt https://example.org/login
# wget: показать заголовки и не скачивать
wget -S --spider https://example.org

Ключ --resolve особенно полезен при переезде сайта: можно проверить новый сервер и сертификат ещё до того, как поменяли DNS-запись. Про настройку самого веб-сервера читайте в статье об установке nginx.

curl POST-запрос и работа с API

Ключ -d сам переключает метод на POST и ставит тип application/x-www-form-urlencoded, поэтому -X POST рядом с ним не нужен.

# форма
curl -d 'login=admin' -d 'remember=1' https://example.org/login
# значение с пробелами и спецсимволами
curl --data-urlencode 'q=привет мир' https://example.org/search
# JSON: --json ставит Content-Type и Accept (curl 7.82+)
curl --json '{"name":"test","tags":["a","b"]}' https://api.example.org/items
# JSON из файла
curl --json @item.json https://api.example.org/items
# старый эквивалент для систем с древним curl
curl -H 'Content-Type: application/json' -d '{"name":"test"}' https://api.example.org/items
# загрузка файла формой multipart
curl -F 'file=@report.pdf' -F 'comment=октябрь' https://example.org/upload
# другие методы
curl -X PUT --json '{"done":true}' https://api.example.org/items/7
curl -X DELETE https://api.example.org/items/7
# авторизация: Basic и Bearer-токен
curl -u admin https://example.org/admin/
curl -H "Authorization: Bearer $API_TOKEN" https://api.example.org/me

Ответ API удобно сразу разбирать через jq: curl -s https://api.github.com/repos/curl/curl | jq .stargazers_count. Токены не пишите прямо в команду: они останутся в истории bash. Держите их в переменной окружения или в файле с правами 600. Для -u admin без пароля curl запросит его интерактивно.

wget тоже умеет POST, но только простой: wget --post-data='a=1&b=2' -O - URL или --post-file=data.json с заголовком --header='Content-Type: application/json'. Для чего-то сложнее берите curl.

Прокси для curl и wget

# HTTP-прокси для одного запроса
curl -x http://10.0.0.1:3128 https://example.org
# SOCKS5, имена резолвит прокси (socks5h)
curl -x socks5h://127.0.0.1:1080 https://example.org
# через переменные окружения (понимают и curl, и wget)
export https_proxy=http://10.0.0.1:3128
export no_proxy=localhost,127.0.0.1,.local
# wget: отключить прокси для одного запуска
wget --no-proxy https://intranet.local/file

Разница между socks5:// и socks5h:// существенна: в первом случае DNS-запрос уходит с вашей машины мимо прокси. wget сам SOCKS не поддерживает, только HTTP-прокси. Постоянные настройки кладут в ~/.curlrc (например строку proxy = "http://10.0.0.1:3128") и ~/.wgetrc (https_proxy = http://10.0.0.1:3128). Если прокси нужен для всей системы, смотрите статью про VPN в Linux.

curl в скриптах и cron

По умолчанию curl считает успехом любой ответ сервера, даже 404 и 500, и возвращает код 0. В скриптах это опасно: скрипт продолжит работу с HTML-страницей ошибки вместо данных. Стандартный набор ключей для автоматизации:

curl -fsSL --connect-timeout 10 --max-time 300 -o data.json https://example.org/data.json || {
  echo "загрузка не удалась" >&2
  exit 1
}
  • -f возвращает ошибку (код 22) при HTTP 400 и выше; --fail-with-body делает то же, но сохраняет тело ответа с текстом ошибки.
  • -s убирает прогресс, -S возвращает сообщения об ошибках.
  • --connect-timeout и --max-time не дают скрипту зависнуть навсегда.

Установщики вида curl -fsSL URL | sh удобны, но выполняют чужой код без просмотра. Безопаснее скачать скрипт в файл, прочитать и только потом запускать. Готовые обёртки удобно планировать по расписанию через cron.

Типичные ошибки и что с ними делать

  • SSL certificate problem: unable to get local issuer certificate. Обновите корневые сертификаты: sudo apt install --reinstall ca-certificates или sudo dnf reinstall ca-certificates. Ключ -k (--no-check-certificate в wget) отключает проверку и подходит только для отладки своего сервера.
  • Could not resolve host. Проблема с DNS, а не с curl. Проверьте resolvectl query example.org, об этом в статье про DNS в Linux.
  • 403 Forbidden в curl, а в браузере всё открывается. Сервер отсекает нестандартный User-Agent. Помогает -A со строкой браузера, но уважайте правила сайта.
  • Скачался HTML вместо архива. Нет -L, или ссылка ведёт на страницу с кнопкой, а не на сам файл.
  • wget в Fedora ругается на незнакомый ключ. Это wget2: часть редких опций wget 1.x не реализована. Используйте curl или найдите классический пакет через dnf search wget.

Все ключи с примерами описаны в официальном руководстве curl.

Частые вопросы

Как скачать файл через curl?

curl -LO URL сохранит файл под именем из адреса, curl -Lo имя URL под своим именем. Ключ -L нужен, чтобы идти по редиректам.

Как продолжить прерванную загрузку?

wget -c URL или curl -C - -LO URL в том же каталоге, где лежит недокачанный файл. Сервер должен поддерживать Accept-Ranges.

Как отправить POST-запрос с JSON через curl?

curl --json '{"key":"value"}' URL. В старых версиях curl до 7.82: curl -H 'Content-Type: application/json' -d '{"key":"value"}' URL.

Как посмотреть только код ответа сервера?

curl -s -o /dev/null -w '%{http_code}\n' URL выведет одно число, например 200 или 404.

Почему в Fedora wget ведёт себя иначе?

С Fedora 40 команду wget предоставляет Wget2. Он почти совместим, но не умеет FTP и WARC и выводит прогресс по-другому.

Документация и источники

Читайте также

Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.