Бывает, что браузера под рукой просто нет. Чистая установка, где ещё ничего не поставлено. Сервер, у которого вместо привычного рабочего стола одна чёрная консоль. Браузер, который после сбоя отказывается запускаться. Или удалённый сеанс, где открыть окно с кнопкой "Скачать" попросту нечем. Во всех этих случаях выручает утилита, о которой многие пользователи Windows и не подозревают: она давно лежит в системной папке и ждёт, когда о ней вспомнят. Речь о curl, настоящем, той самой, которой пользуются разработчики по всему миру. Одной строки хватает, чтобы забрать файл по адресу, а несколько дополнительных ключей превращают её в аккуратного загрузчика с докачкой, повторами и контролем ошибок.

Где находится curl в Windows, с какой версии он есть и чем отличается от одноимённой команды PowerShell

Утилита вошла в состав системы в декабре 2017 года: с тестовой сборки Windows 10 под номером 17063 она стала штатным компонентом, а в обычных выпусках появилась с версией 1803. Сегодня она есть в каждой установке Windows 10 и Windows 11. Файл лежит по адресу C:\Windows\System32\curl.exe, так что запускать её можно из любой папки без установки и без настройки путей.

Первая сборка, попавшая в систему, была версии 7.55.1 из августа 2017 года. Обновляется утилита вместе с Windows, и в свежих системах версия заметно новее. Проверить, что именно стоит на конкретном компьютере, можно одной командой:

curl --version

Номер версии здесь важен не из любопытства. Часть удобных ключей появилась позже: например, ключ --output-dir, который задаёт папку для сохранения, добавлен в версии 7.73.0, а --retry-all-errors для повторных попыток при любых сбоях - в 7.71.0. Если на старой сборке Windows 10 стоит древняя версия, эти ключи вызовут сообщение о неизвестной опции, и придётся обходиться более простыми средствами. Сборка от Microsoft вообще устроена отдельно от версии с сайта проекта: набор включённых возможностей у неё может отличаться, а по номеру она нередко отстаёт.

Есть и ловушка, в которую падают почти все, кто запускает curl в PowerShell. В Windows PowerShell 5.1, который стоит в системе по умолчанию, слово curl является псевдонимом совсем другой команды, Invoke-WebRequest. Ключи у неё свои, и привычная строка с -O вызовет путаное сообщение об ошибке параметра. Обойти это просто: писать имя вместе с расширением.

curl.exe -O https://example.com/files/report.pdf

В классической командной строке cmd такой проблемы нет, там слово curl всегда запускает настоящую утилиту. Во всех примерах ниже подразумевается именно она, а при работе в PowerShell к имени достаточно дописать .exe.

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

Самый частый вопрос звучит так: что произойдёт, если просто дать curl адрес? Ответ неожиданный. Утилита скачает содержимое и выведет его прямо в окно консоли. Для текстовой страницы это нормально, а для архива или установщика окно заполнится бессмысленными символами, и консоль придётся закрывать. Чтобы данные легли в файл, нужен один из двух ключей.

Заглавный ключ -O сохраняет файл под тем именем, которое указано в конце адреса, в текущую папку:

curl -O https://example.com/files/report.pdf

Строчный ключ -o позволяет задать имя самостоятельно, в том числе с полным путём:

curl -o C:\Downloads\monthly.pdf https://example.com/files/report.pdf

Если нужно собрать в одну папку несколько загрузок, удобен ключ --output-dir. Он действует вместе с -O и -o, а несуществующую папку создаёт только при наличии ещё одного ключа, --create-dirs:

curl --create-dirs --output-dir C:\Downloads\docs -O https://example.com/files/report.pdf

Несколько файлов за один вызов получаются повторением ключа: curl -O адрес1 -O адрес2. Для случаев, когда сервер сам сообщает правильное имя файла, добавляется ключ -J. Он берёт имя из служебного заголовка ответа и полезен, когда адрес заканчивается неудобной длинной строкой с параметрами.

Две мелочи стоит запомнить сразу. Первая: если файл с таким именем уже существует, curl перезапишет его без вопросов. Защититься можно ключом --no-clobber, который появился в версии 7.83.0. Вторая: адреса с символом & в классической консоли нужно брать в двойные кавычки, иначе cmd примет знак за разделитель команд и обрежет адрес на полуслове. Одинарные кавычки в cmd не работают, годятся только двойные.

Редиректы, ошибки сервера и проверка размера файла перед загрузкой

Начинающие часто сталкиваются с загадкой: файл скачался, но весит триста байт и открывается как текст. Причина в том, что сервер ответил перенаправлением, то есть сообщил, что настоящий файл лежит по другому адресу, а curl по умолчанию этому указанию не следует. Он честно сохранил короткую служебную страницу. Ключ -L включает следование перенаправлениям, и загрузка идёт к настоящему адресу.

Вторая беда зеркальная: адрес неверный, сервер отвечает ошибкой 404, а curl преспокойно записывает страницу с ошибкой в файл с именем нужного документа. Выглядит как успех, а на деле в файле лежит текст сообщения. Ключ -f заставляет утилиту считать ошибки сервера настоящими ошибками: файл не создаётся, а в консоли появляется короткое сообщение. Если нужно ещё и сохранить тело ответа с пояснением, есть вариант --fail-with-body из версии 7.76.0.

Поэтому надёжная основа для любой загрузки состоит из двух ключей сразу:

curl -fL -O https://example.com/files/setup.exe

Перед большой загрузкой полезно узнать размер. Запрос с ключом -I получает только заголовки ответа, не скачивая сам файл:

curl -I -L https://example.com/files/setup.exe

В выводе есть строка Content-Length, где размер указан в байтах, и строка Content-Type, где виден тип содержимого. Допустим, значение равно 157286400. Делим на 1024 дважды: 157286400 / 1024 / 1024 = 150, то есть файл весит ровно 150 мегабайт. Если на диске остаётся всего 100 мегабайт, команду можно не запускать.

Для скриптов пригодится проверка кода ответа без вывода каких-либо данных на экран:

curl -s -o nul -w "%{http_code}" -I https://example.com/files/setup.exe

Ключ -s подавляет индикатор, -o nul отправляет тело в пустое устройство Windows, а -w печатает шаблон с кодом ответа. Число 200 означает, что файл доступен, 404 - что адреса не существует. Когда нужно разобраться, что происходит между клиентом и сервером, включают подробный режим ключом -v: в нём видны отправленные заголовки, этапы согласования защищённого соединения и все ответы.

Докачка оборванных загрузок, повторные попытки и ограничение скорости канала

Крупные файлы любят обрываться на девяносто процентах. Для таких случаев у curl есть ключ -C с одиночным дефисом в качестве значения:

curl -fL -C - -O https://example.com/files/setup.exe

Утилита сама смотрит, сколько байт уже лежит на диске, и просит сервер прислать остаток. Работает это, если сервер умеет отдавать файлы по частям. Если не умеет, curl сообщит, что докачка невозможна, и тогда придётся начинать заново.

Сетевые сбои бывают короткими: пропало соединение на секунду, сервер не ответил. Ключ --retry указывает, сколько раз пробовать заново, а --retry-delay задаёт паузу между попытками в секундах. Обычные повторы срабатывают при временных ошибках, а ключ --retry-all-errors расширяет их на любые.

curl -fL -C - --retry 5 --retry-delay 10 -O https://example.com/files/setup.exe

Пять попыток по десять секунд даёт не больше пятидесяти секунд ожидания на сбой, и на ненадёжном канале это нередко решает дело.

Бывает и противоположная проблема: загрузка слишком хорошо работает и забирает весь канал, так что у остальных программ пропадает интернет. Ключ --limit-rate задаёт потолок скорости. Значение принимает с суффиксами K, M и G. Ограничение в 2M означает два мегабайта в секунду, то есть около 16 мегабит в секунду. Простой расчёт показывает, чего ждать: файл в 150 мегабайт при такой скорости скачается за 150 / 2 = 75 секунд.

Внешний вид индикатора тоже настраивается. По умолчанию curl выводит таблицу с процентами, объёмом и скоростью. Ключ -# заменяет её на компактную полосу из решёток. Ключ -s скрывает всё, а в связке с -S возвращает только сообщения об ошибках, что идеально для скриптов. В версии 7.67.0 появился ключ --no-progress-meter, который отключает только индикатор и оставляет сообщения.

Адреса с авторизацией, пользовательские заголовки и отправка данных на сервер

Не все файлы лежат в открытом доступе. Для ресурсов с паролем служит ключ -u:

curl -fL -u username -O https://example.com/private/data.zip

Если пароль в команде не указывать, а оставить только имя пользователя, curl спросит его сам. Это лучше, чем вписывать пароль в строку: всё набранное в консоли попадает в историю и может быть увидено позже.

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

curl -fL -H "Authorization: Bearer ТОКЕН" -H "Accept: application/json" -o result.json https://example.com/api/items

Утилита умеет и отправлять данные, а не только получать. Ключ -d передаёт тело запроса, и вместе с ним curl автоматически переходит к методу POST. Для структуры с кавычками в cmd есть неудобство: двойные кавычки внутри двойных приходится экранировать обратной косой чертой. Поэтому для сложных тел надёжнее положить данные в файл и сослаться на него знаком @:

curl -fL -H "Content-Type: application/json" -d @data.json -o answer.json https://example.com/api/send

В версии 7.82.0 появился ещё и ключ --json, который сразу выставляет нужные заголовки. Кроме протокола HTTP, утилита понимает и другие: из списка включённых в сборку Microsoft известны FTP, FTPS, IMAP, POP3, SMTP, TFTP и некоторые другие. Файл с FTP-сервера забирается так же, как и по HTTP: curl -O ftp://example.com/pub/archive.zip.

Защищённые соединения, ошибки проверки сертификата и сверка контрольной суммы

Адреса с https проходят проверку сертификата. В сборке Windows для этого используется встроенный механизм системы под названием Schannel. Он же отвечает за самую известную ошибку curl в Windows. Если в окружении закрыт доступ к службам проверки отзыва сертификатов (так бывает в корпоративных сетях и за некоторыми межсетевыми экранами), утилита сообщит, что функция отзыва не смогла проверить сертификат. Решение есть в виде двух ключей. Первый, --ssl-no-revoke, полностью отключает проверку отзыва. Второй, --ssl-revoke-best-effort из версии 7.70.0, мягче: если данные об отзыве получить не удалось, проверка пропускается, а остальные проверки сохраняются.

Ключ -k, отключающий проверку сертификата целиком, лучше оставлять для разовой диагностики. Он лишает защищённое соединение главного смысла: утилита перестаёт различать настоящий сервер и подставной.

Скачанный файл неплохо проверить, прежде чем запускать. Многие поставщики публикуют контрольную сумму рядом с загрузкой. Вычислить такую же для локальной копии можно командой PowerShell:

Get-FileHash .\setup.exe -Algorithm SHA256

Если две строки из шестидесяти четырёх символов совпали, файл дошёл целым и не подменён по дороге. Если хоть один символ отличается, файлу доверять нельзя, и лучше скачать его заново, а не гадать, что пошло не так. Второе правило проще: скачивать установщики стоит только с адресов самих поставщиков. А запускать загруженный сценарий, не открыв его и не прочитав, нельзя ни при каких обстоятельствах.

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

Когда файлов много, на помощь приходит цикл. Адреса записываются в текстовый файл urls.txt по одному на строку, а пакетный файл перебирает их по очереди:

@echo off
for /f "usebackq delims=" %%U in ("urls.txt") do curl -fL --retry 3 -O "%%U"

Двойной знак процента нужен внутри пакетного файла, а при вводе прямо в консоли пишется один. Для ускорения в версии 7.66.0 появилась параллельная загрузка ключом -Z: несколько адресов в одной команде скачиваются одновременно.

curl -Z -fL -O https://example.com/a.zip -O https://example.com/b.zip

Результат любого запуска можно проверить в скрипте через код возврата. Если после команды переменная %errorlevel% равна нулю, загрузка прошла успешно, любое другое значение сигнализирует о сбое, и можно повторить попытку или написать в журнал. Закрепить такой скрипт за расписанием помогает планировщик заданий.

Теперь самый показательный сценарий: компьютер без браузера, на котором нужно получить установщик. Порядок действий обычно укладывается в шесть шагов:

  1. открыть консоль и убедиться в наличии утилиты командой curl --version;
  2. запросить заголовки командой curl -I -L с адресом файла и узнать его размер;
  3. скачать файл командой с ключами -fL и -O, а при нехватке канала добавить --limit-rate;
  4. при обрыве повторить ту же команду с ключом -C -, чтобы докачать недостающее;
  5. сверить контрольную сумму через Get-FileHash;
  6. запустить установщик из консоли, указав его имя.

У PowerShell есть и свои средства. Команда Invoke-WebRequest с параметром -OutFile скачивает файл без curl, а командлет Start-BitsTransfer использует фоновую службу передачи, которая умеет продолжать загрузку после перезагрузки компьютера. Но curl остаётся самым универсальным вариантом: одинаково ведёт себя в консоли, в пакетных файлах и в десятках других систем, а набор ключей, выученный один раз, пригождается везде.

Нехитрая комбинация из трёх ключей, -f, -L и -O, закрывает девять случаев из десяти. Остальное добавляется по мере надобности: докачка, когда канал нестабилен, ограничение скорости, когда нельзя занимать весь интернет, заголовки, когда без них сервер не отвечает. Браузер для скачивания файла нужен куда реже, чем принято думать.