Примеры использования 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/.