Примеры использования cURL
Однако чаще всего curl
используется только для простых задач, таких как загрузка файла или проверка доступности сайта, а ведь он может гораздо больше!
И в этой статье рассмотрим именно такие крутые примеры и трюки, демонстрирующие, почему curl
является удивительным и недооценённым инструментом…
Глоббинг
Во-первых, глоббинг, позволят выполнять несколько запросов с помощью одной команды curl
:
curl -s "https://jsonplaceholder.typicode.com/users/[1-3]" | jq -s .
curl -s "https://jsonplaceholder.typicode.com/users/[0-10:2]" | jq -s .
curl -s "https://jsonplaceholder.typicode.com/photos/{1,6,35}" | jq -s .
curl -s "https://jsonplaceholder.typicode.com/users/[1-3]" -o "file_#1.json"
Первые две команды показывают, как можно выполнить ряд запросов — первая команда производит запросы к .../users/1
, .../users/2
и .../users/3
, а вторая использует опцию step
, что даёт 2
, 4
, 6
, 8
и 10
. Учитывая, что эти конкретные запросы возвращают JSON, объединим их с jq ...
с помощью оператора -s
(slurp), объединяющего ответы отдельных запросов в единый массив.
В третьем примере вместо диапазона используется список конкретных чисел — это также работает для символов и слов — например, можно использовать группировку для выполнения запросов с несколькими протоколами: {http,https}://...
Последний пример сочетает глоббинг и выходные переменные, где переменная #1
в имени файла ссылается на диапазон [1-3]
. В результате будут созданы файлы file_1.json
, file_2.json
и file_3.json
.
Конфигурационные файлы
Чаще всего при использовании curl
необходимо передавать одни и те же параметры командной строки, такие как настройки прокси, таймауты запросов, заголовки и т.д. Именно здесь может пригодиться конфигурационный файл curl
с именем .curlrc
:
# ~/.curlrc
# some headers
-H "Upgrade-Insecure-Requests: 1"
-H "Accept-Language: en-US,en;q=0.8"
# follow redirects
--location
Это просто текстовый файл, где каждая строка представляет собой одну опцию, которая будет передана curl
. Он автоматически считывается из ~/.curlrc
, поэтому не нужно никаких дополнительных флагов, но можно использовать -K
, чтобы переопределить или указать другое местоположение, например:
curl -K .curlrc https://google.com
Аналогично флагам и опциям, можно передать учётные данные. Это можно сделать с помощью опции --user
, но тогда учётные данные останутся в истории командной строки, поэтому вместо этого лучше использовать файл .netrc
, поддерживаемый curl
:
# ~/.netrc
machine https://authenticationtest.com/HTTPAuth/
login user
password pass
Формат включает machine
(URL), login
и password
— они могут быть в одной строке или как показано выше, также можно разместить записей несколько в одном файле. Для использования просто передайте его в curl
, например:
curl --netrc-file .netrc https://authenticationtest.com/HTTPAuth/
Параллельные запросы
О диапазонах запросов уже говорилось в разделе глоббинг, но как насчёт распараллеливания? Ну, curl может сделать и это:
curl -I --parallel --parallel-immediate --parallel-max 3 --config websites.txt
curl -I --parallel --parallel-immediate --parallel-max 3 stackoverflow.com google.com example.com
Всё, что нужно сделать, это добавить --parallel
(или -Z
), и curl
будет открывать до 50 параллельных соединений (можно изменить с помощью --parallel-max N
). Также обратите внимание на то, как указывается URL — первая опция --config
и текстовый файл, выглядящий следующим образом:
url = "stackoverflow.com"
url = "google.com"
url = "example.com"
Другой вариант — просто передать все URL в командную строку. Оба варианта также работают с непараллельными запросами!
Форматирование и переменные
curl
может выводить множество данных, и иногда это может быть слишком многословным, многословным и ненужным. К счастью, можно использовать форматирование вывода, чтобы выводить только то, что интересует:
curl --silent --output /dev/null --show-error -w @format.txt http://example.com/
# Type: text/html; charset=UTF-8
# Code: 200
#
# From 8.1.0:
# Scheme: http
# Host: example.com
# Port: 80
#
# Read header content (v7.83.0):
# Server: Sat, 29 Jun 2024 13:01:30 GMT
Для этого используется опция -w
и передаётся формат файла. Чтобы получить такой результат, как показано выше, можно использовать:
# format.txt
Type: %{content_type}\nCode: %{response_code}\n\n
From 8.1.0:\n\n
Scheme: %{url.scheme}\n
Host: %{url.host}\n
Port: %{url.port}\n
Read header content (v7.83.0):\n
%header{date}
Каждая переменная заключена в %{...}
. Они могут быть как простыми, например response_code
, так и частью url.<NAME>
, ссылающейся на компоненты URL, такие, как хост или порт. Наконец, можно вывести заголовки ответа с помощью переменных %header{HEADER_NAME}
.
Одним из многих удобных случаев использования форматирования является измерение времени запроса/ответа, что можно сделать с помощью следующего формата:
# format.txt
time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_redirect: %{time_redirect}s\n
time_starttransfer: %{time_starttransfer}s\n
----------\n
time_total: %{time_total}s\n
# Результат:
time_namelookup: 0.000765s
time_connect: 0.111908s
time_appconnect: 0.000000s
time_pretransfer: 0.111967s
time_redirect: 0.000000s
time_starttransfer: 0.223373s
----------
time_total: 0.223992s
Полный список переменных см. в документации.
Тестирование и диагностика неполадок
Чаще всего curl
используется для диагностики (сетевых) неполадок — зачастую простого запроса к определённому URL достаточно для получения информации, но есть и другие возможности, например, можно заставить использовать определённый локальный сетевой интерфейс:
ip link show
# ...
# 3: wlp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
curl --interface wlp5s0 https://example.com
Аналогичным образом можно принудительно установить определённый DNS-сервер:
curl --dns-ipv4-addr 1.1.1.1 https://example.com
Или можно проверить на таймаут и перехватить код выхода (коды выхода):
curl --connect-timeout 30 --silent --output /dev/null \
--show-error -w 'Total: %{time_total}s\n' http://google.com/ || EXIT_CODE=$?
if [ $EXIT_CODE = 28 ]
then
echo "Cannot connect (Timeout)."
else
echo "Can connect."
fi
Это может быть удобно, например, для проверки работы прокси-сервера (с помощью -x http://proxy.example.com:80
).
trurl
curl
— это не просто CLI-инструмент: в проект входит libcurl
, а также trurl
, который с удовольствием продемонстрирую здесь.
trurl
— это специализированный инструмент для разбора URL-адресов, являющийся родственным проектом curl
. Его можно установить из исходных текстов:
sudo apt-get install libcurl4-openssl-dev
git clone https://github.com/curl/trurl.git
cd trurl
make
# ...
А вот несколько примеров использования trurl
:
trurl --url https://example.com/some/path/to/file.html --get '{path}'
# /some/path/to/file.html
trurl --url "https://example.com/?name=hello" --append query=key=value
# https://example.com/?name=hello&key=value
# Parse as JSON:
./trurl --url "https://example.com/?name=hello" --json
# [
# {
# "url": "https://example.com/?name=hello",
# "parts": {
# "scheme": "https",
# "host": "example.com",
# "path": "/",
# "query": "name=hello"
# },
# "params": [
# {
# "key": "name",
# "value": "hello"
# }
# ]
# }
# ]
Первый показывает, как можно извлечь компонент URL, здесь это путь, но может быть, например, url, схема, пользователь, пароль, опции или хост.
Второй использует функцию append
, чтобы добавить параметр запроса в URL.
И последний пример демонстрирует опцию --json
, выводящую разобранный URL в формате JSON, который отлично подходит для дальнейшей обработки.
trurl может многое другое — вы можете посмотреть это видео или руководство (примеры внизу).
Отправка/загрузка данных
Чаще всего curl
используется для скачивания или запроса данных, но он также может (очевидно) отправлять данные. В отправке данных с помощью curl
нет ничего нового, верно?
curl -X POST "https://httpbin.org/post" -H "accept: application/json" --json '{"key": "value"}'
Но отправка JSON в таком виде с необходимостью чередовать одинарные и двойные кавычки быстро надоедает, есть лучший способ:
jo -p key=value | curl -X POST "https://httpbin.org/post" -H "accept: application/json" --json @-
Думаю, все знакомы с разбором JSON-вывода curl
с помощью jq
, но как насчёт обратного? — Выше был использован инструмент jo
, легко создающий JSON, который можно передать в curl
с помощью опции --json
.
Естественно, опция --json
может также принимать данные из файла, например, с помощью --json @data.json
.
Протоколы
И последнее, но не менее важное, это протоколы — обычно используются только HTTP или HTTPS, но curl
поддерживает множество протоколов.
В частности, хочу упомянуть telnet
, удобный для проверки того, слушает ли сервер определённый порт, но что делать, если на сервере/машине отсутствует и нет возможности установить telnet
? Просто используйте curl
:
# То же самое, что telnet example.com 1234
curl telnet://example.com:1234
Некоторые из наиболее странных (забавных) вариантов протоколов — IMAP, POP3 и SMTP для электронной почты, что означает, что можно читать и отправлять письма с помощью curl
. Чтобы прочитать их:
curl --url "imaps://imap.gmail.com:993/Inbox;UID=1" --user "user@gmail.com:PASSWORD"
Чтобы это работало именно с GMail, необходимо создать пароль приложения, который менее надёжным, чем обычный пароль. Если действительно хотите попробовать, ознакомьтесь с Gmail IMAP документацией и этими запросами для вдохновения.
Для отправки электронной почты можно использовать:
curl smtp://mail.example.com \
--mail-from me@example.com \
--mail-rcpt someone@example.com \
--upload-file message.txt \
-u "me@example.com:PASSWORD"
message.txt
— это собственно письмо, которое должно соответствовать определённому формату, примеры смотрите на этой странице.
Заключение
Мы подошли к концу, и я уверен, что это было не менее 10 примеров (перестал считать). Но, честно говоря, это лишь малая часть — ведь мы даже не коснулись libcurl
, являющейся основной частью curl
.
С помощью curl
можно сделать гораздо больше, поэтому рекомендую изучить как документацию, так и https://everything.curl.dev/.