Использование curl в Linux
Общие сведения
Сurl и браузеры не всегда одинаково обрабатывают URL-адреса
Иногда разница между тем, что вы видите в адресной строке браузера, и тем, что вы можете передать в curl, может быть значительной
Curl поддерживает следующие протоколы: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS и WSS
Синтаксис URL-адреса зависит от протокола
Можно указать любое количество URL-адресов в командной строке. Они извлекаются последовательно в указанном порядке, если не используется -Z, --parallel. Можно указать параметры командной строки и URL-адреса в смешанном виде и в любом порядке в командной строке
Когда клиент подключается к «example.com» и запрашивает ресурс «/», он отправляет запрос GET без тела запроса:
GET / HTTP/1.1
User-agent: curl/2000
Host: example.com
При этом сервер может ответить так:
HTTP/1.1 200 OK
Server: example-server/1.1
Content-Length: 5
Content-Type: plain/text
hello
Заголовок сервера содержить код ответа и поддерживаемую версию
Установка
#Установка
apt install curl
#Если есть необходимость создавать приложения на основе libcurl
apt install libcurl4-openssl-dev
Подробный режим
В режиме verbos curl выводит информацию о том, как имя соотносится с IP-адресом и к какому порту он подключился
Если используется URL-адрес HTTPS:// вместо HTTP-адреса, то увидим множество строк, объясняющих, как curl использует сертификаты центра сертификации для проверки сертификата сервера, а также некоторые сведения из сертификата сервера и т. д. В том числе выбранные шифры и другие сведения о TLS.
curl -v http://example.com
Опция -s (или --silent), напротив отображает меньше информации, но вывод ошибок можно оставить с помощью опции -S или --show-error.
Ошибки
curl возвращает код завершения своей работы для последнего использованного URL-адреса. Чтобы curl завершал работу с ошибкой для первого неудачного URL-адреса в наборе, необходимо использовать опцию --fail-early
Трассировки
Бывают случаи, когда -v недостаточно
--trace [filename] сохраняет полную трассировку в заданном имени файла. Вы также можете использовать '-' (один минус) вместо имени файла, чтобы передать его в стандартный вывод.
Каждый отправленный и полученный байт отображается отдельно в шестнадцатеричном формате. Полученные заголовки выводятся построчно.
Если шестнадцатеричные числа не помогают, можно попробовать --trace-ascii [filename] вместо них.
Параметр --trace-ids позволяет увидеть, как curl добавляет два числа во все трассировки: номер подключения и номер передачи. Это два отдельных идентификатора, потому что подключения могут использоваться повторно, а несколько передач могут использовать одно и то же подключение
curl --trace dump http://example.com
Если объёма данных трассировки недостаточно. Например, возникла проблема на более низком уровне протокола, и хотите её отладить, curl предоставляет опцию --trace-config
С помощью этой опции можно указать curl, что нужно также включать в журнал сведения о компонентах, которые по умолчанию не включаются, например, сведения о протоколе TLS, HTTP/2 или HTTP/3. Также есть удобные опции для добавления идентификаторов подключения и передачи данных, а также отметок времени.
Опция --trace-config принимает аргумент, в котором указывается разделённый запятыми список областей, которые необходимо отслеживать
Например:
curl --trace-config ids,http/2 https://example.com
ids те же идентификаторы, что и --trace-ids предоставляет
time тот же выходной сигнал по времени, что и --trace-time обеспечивает
all покажите все возможное
tls Сведения об обмене по протоколу TLS
http/2 Информация о кадре HTTP/ 2
http/3 Информация о кадре HTTP/ 3
* дополнительные в будущих версиях
Перенаправление
#Следовать за перенаправлением
curl -vL http://example.com
Сохранить в файл
Опция -o указывает где сохранять вывод
Если вы используете командную строку с двумя URL-адресами, вы должны указать curl, как обрабатывать оба из них. Параметры -o и -O указывают curl, как сохранять вывод для одного из URL-адресов, поэтому вы можете использовать столько этих параметров, сколько URL-адресов в командной строке.
Если в командной строке URL-адресов, чем вариантов вывода, содержимое URL-адреса без соответствующей инструкции по выводу отправляется в стандартный вывод.
Использование флага --remote-name-all автоматически заставляет curl действовать так, как если бы -O использовался для всех указанных URL-адресов, для которых не задана опция вывода.
Подробнее об этом в источнике: https://everything.curl.dev/cmdline/urls/options.html
curl -o curl.out https://netbash.ru
#Пример использования команды curl с опцией --remote-name для загрузки файла с сохранением вывода под именем, указанным в URL
curl --remote-name https://example.com/filename.zip
#В этом примере файл будет сохранён в директорию /tmp.
#Если директория не существует, для её создания используется опция --create-dirs
curl --remote-name --output-dir /tmp http://httpbingo.org/uuid
#Сохранение разных страниц сайта
curl "http://example.com/{one,two}" -o "file_#1.txt"
#Сохранение страниц двух разных сайтов
curl "http://{one,two}.example.com" -o "file_#1.txt"
#
curl "http://{site,host}.host[1-5].example.com" -o "subdir/#1_#2"
Аргументы с пробелами
#Пример1
curl -A "I am your father" http://example.com
JSON
#post запрос в виде json
curl -d '{ "name": "Darth" }' http://example.com
Отправка данных из файла
#Предположим, что файл, содержащий вышеупомянутые данные, называется «json»:
curl -d @json http://example.com
Отрицание
curl --no-verbose http://example.com
Запрос
Часть URL-адреса, содержащая запрос, — это данные, которые находятся справа от знака вопроса (?), но слева от фрагмента, который начинается с хэша (#)
Запрос может представлять собой любую последовательность символов, если они закодированы в URL. Обычно используется последовательность пар «ключ-значение», разделённых амперсандами (&). Например, https://example.com/?name=daniel&tool=curl
Чтобы помочь пользователям создавать такие наборы запросов с правильной кодировкой, curl предлагает параметр командной строки --url-query [content]. Этот параметр добавляет содержимое, обычно пару «имя + значение», в конец части запроса в указанном URL-адресе
При добавлении частей запроса curl добавляет разделители амперсандов
Синтаксис идентичен тому, что используется в --data-urlencode с одним дополнением: префиксом +
content: закодировать содержимое URL-адреса и добавить его в запрос. Содержимое не должно содержать символов = или @, так как в этом случае синтаксис будет соответствовать одному из других вариантов ниже
=content: закодировать содержимое и добавить его в запрос. Первый символ = не включается в данные
name=content: закодировать часть содержимого в URL и добавьте её в запрос. Часть имени уже должна быть закодирована в URL
@filename: загрузить данные из указанного файла (включая все символы новой строки), закодировать эти данные в URL и добавьте их в запрос
name@filename: загрузить данные из указанного файла (включая все новые строки), закодировать эти данные в URL-адресе и добавить их в запрос. К имени добавляется знак равенства, в результате чего получается name=urlencoded-file-content. Имя уже должно быть закодировано в URL-адресе.
+content: Добавить содержимое в запрос, не выполняя никакого кодирования.
Фрагмент
URL-адреса могут содержать фрагментную часть. Которая начинается с символа решетки (#) и имени для конкретного элемента на веб-странице в браузерах. Пример такого URL-адреса может выглядеть так:
https://www.example.com/info.html#the-plot
curl отлично поддерживает фрагменты, когда ему передаётся URL-адрес, но часть с фрагментом на самом деле никогда не отправляется по сети, поэтому для операций curl не имеет значения, присутствует она или нет
Если необходимо чтобы символ # был частью пути, а не разделял фрагмент, необходимо передать его в URL-кодировке как %23:
curl https://www.example.com/info.html%23the-plot
Url globbing
Иногда есть необходимость получить набор URL-адресов, которые в основном одинаковы, лишь небольшая часть url меняется между запросами. Возможно, это числовой диапазон или набор имён. Curl предлагает «globbing» как способ легко указать множество таких URL-адресов
Для этого используются зарезервированные символы [] и {}, которые обычно не могут быть частью допустимого URL, за исключением числовых IPv6-адресов. Если подстановка мешает, отключите её с помощью -g, --globoff
При использовании последовательностей [ ] или {}, необходимо заключать полный URL-адрес в двойные кавычки, чтобы оболочка не вмешивалась в него. Это также относится к другим специальным символам, таким как, например, '&', '?' и '*'
В то время как большинство функций, связанных с передачей данных в curl, предоставляются библиотекой libcurl, функция сопоставления URL-адресов — нет
Числовой диапазон
curl -O "http://example.com/[1-100].png"
#изображения с чётными номерами
curl -O "http://example.com/[0-100:2].png"
Алфавитные диапазоны
curl -O "http://example.com/section[a-z].html"
Список
curl -O "http://example.com/{one,two,three,alpha,beta}.html"
Комбинации
curl -O "http://example.com/{Ben,Alice,Frank}-{100x100,1000x1000}.jpg"
#или
curl -O "http://example.com/chess-[0-7]x[0-7].jpg"
Кодирование скобок
[ %5b
] %5d
{ %7b
} %7d
Или отключить глобализацию с помощью -g или --globoff
Параллельные передачи
curl предлагает опцию -Z (или --parallel), которая указывает на необходимость выполнения указанных операций параллельно. Если эта опция включена, curl выполняет множество операций одновременно, а не последовательно. По умолчанию он выполняет до 50 операций одновременно, и как только одна из них завершается, запускается следующая.
В случаях, когда есть необходимость загрузить много файлов из разных источников, некоторые из которых могут загружаться медленно, а некоторые — быстро, это может значительно ускорить процесс
Если 50 параллельных переводов недостаточно, можно изменить это с помощью опции --parallel-max
curl --parallel "http://{site,host}.host[1-5].example.com" -o "subdir/#1_#2"
trurl
Подробнее об вспомогательном инструменте trurl, в источнике: https://everything.curl.dev/cmdline/urls/trurl.html
Конфигурационный файл
Использование опции -K или длинной формы --config указывает curl на необходимость чтения из файла конфигурации
Указанный путь к файлу относится к текущему каталогу
curl \
--config configFile.txt \
--url https://example.com
Сам конфиграционный файл может выглядеть примерно следующим образом:
# curl config file
# Follow redirects
--location
# Do a HEAD request
--head
user-agent "Everything-is-an-agent"
#Или
user-agent = "Everything-is-an-agent"
url = https://example.com
Когда использовать кавычки
Когда параметр содержит пробелы или начинается с символов : или =.
Когда нужно использовать управляющие последовательности (доступные варианты: \\, \", \t, \n, \r и \v. Обратная косая черта перед любой другой буквой игнорируется)
Если параметр, содержащий пробелы, не заключён в двойные кавычки, curl считает следующий пробел или новую строку концом аргумента
Конфигурационный файл по умолчанию
При вызове curl он всегда (если не используется -q), проверяет наличие файла конфигурации по умолчанию и использует его, если находит.
Curl ищет файл конфигурации по умолчанию в следующих местах в указанном порядке:
$CURL_HOME/.curlrc
$XDG_CONFIG_HOME/.curlrc (Добавлено в версии 7.73.0)
$HOME/.curlrc
Global
Можно указать несколько URL-адресов или их частей, заключив списки в фигурные скобки или диапазоны в квадратные скобки. Это называется "глобализацией"
#Пример1
curl http://crm.{mail,yandex}.ru
#Пример2
curl ftp://ftp.example.com/file[1-100].txt
#Пример3
curl ftp://ftp.example.com/file[a-z].txt
#Пример4, можно использовать несколько шаблонов рядом друг с другом
http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html
При использовании последовательностей [] или {} при вызове из командной строки вам, вероятно, придется заключить полный URL-адрес в двойные кавычки, чтобы избежать вмешательства оболочки в его работу. Это также относится к другим символам, которые считаются специальными, например, "&", "?" и "*"
При необходимости Отключите глобализацию с помощью -g, --globoff
Переменные
curl поддерживает переменные командной строки. Задать переменные можно с помощью --variable name=content или --variable name@file
Содержимое переменной может быть расширено в параметрах опции с помощью "{{name}}", если имя опции имеет префикс "--expand-". При этом будет вставлено содержимое переменной "name" или пустое поле, если имя не существует в качестве переменной. Вставьте "{{" в строку дословно, добавив к ней обратную косую черту, например "\{{"
Переменные среды можно определять с помощью --variable %VARNAME
Например: --variable '%USER'
Пользователь также может задать значение по умолчанию, если переменная среды не существует, с помощью =content или @file
Далее переменную можно вставить в url
--expand-url = "https://example.com/api/{{USER}}/method"
#Пример1
curl --variable host=netbash --expand-url "https://{{host}}.ru"
#Пример2
curl --variable %USER --expand-url "https://netbash.ru/{{USER}}"
#Пример3
curl --variable %HOME --expand-variable test@{{HOME}}/text.txt --expand-data "{{fix:trim:url}}" https://netbash.ru
#присвоить переменной содержимое обычного текстового файла
curl --variable %USER@filename.txt --expand-url "https://netbash.ru/{{USER}}"
#Сам параметр --variable также можно расширить, что позволяет присваивать переменным содержимое других переменных
curl \
--expand-variable var1={{var2}} \
--expand-variable fullname="Mrs {{first}} {{last}}" \
--expand-variable source@{{filename}}
#В конфигурационном файле это будет выглядить так:
# Curl config file
variable host=example
expand-variable url=https://{{host}}.com
expand-variable source@{{filename}}
Источник1: https://daniel.haxx.se/blog/2023/07/31/introducing-curl-command-line-variables/
Функции
При расширении переменных curl предлагает набор функций для изменения способа их расширения. Функции применяются с помощью двоеточия + имени функции после переменной, например так: {{varName:function}}
К переменной можно применить несколько функций. Они применяются в порядке слева направо: {{varName:func1:func2:func3}}
Доступны следующие функции: trim, json, url и b64
Функция trim
Функция: trim
Расширяет переменную без начальных и конечных пробелов. Пробелы определяются как:
горизонтальные выступы
пробелы
новые линии
вертикальные выступы
подача формы и возврат каретки
Это особенно полезно при чтении данных из файлов.
--expand-url "https://example.com/{{path:trim}}"
Полный разбор функций можно увидеть в источнике: https://everything.curl.dev/cmdline/variables.html
Пароли
Один из способов избежать передачи имени пользователя и пароля в командной строке — использовать файл .netrc или файл конфигурации. Можно также использовать опцию -u без указания пароля, и тогда curl будет запрашивать его у пользователя при запуске.
Командная строка отправляет учётные данные пользователя на HTTP-сервер, который использует протокол передачи данных в открытом виде, что позволяет злоумышленникам перехватывать соединение и видеть, что отправляется. В этом примере командной строки curl использует базовую аутентификацию HTTP, которая совершенно небезопасна
Самый простой способ — использовать зашифрованные версии протоколов. Используйте HTTPS вместо HTTP, FTPS вместо FTP и так далее
Если нужен HTTP, следует использовать такие методы как: Digest (--digest), Negotiate (--negotiate.) и NTLM (--ntlm)
Прогресс
В curl есть встроенный индикатор выполнения. Когда curl вызывается для передачи данных (загрузки или выгрузки), он может отображать этот индикатор на экране терминала
Можно принудительно отключить индикатор выполнения с помощью опции -s / --silent
В Curl также есть альтернативный и более простой индикатор выполнения, который можно включить с помощью -# / --progress-bar
Индикатор выполнения отображает количество байт в секунду
Но можно использовать другие еденицы:
K 2^10 килобайт
M 2^20 мегабайт
G 2^30 гигабайт
T 2^40 терабайт
P 2^50 петабайт
% Total % Received % Xferd Average Speed Time Curr.
Dload Upload Total Current Left Speed
0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287
% Процент выполненного перевода от общего объема перевода
Total Общий размер всего ожидаемого перевода (если известен)
% Процент завершения загрузки
Received Количество загруженных в данный момент байт
% Процент завершенной загрузки
Xferd Текущее загруженное количество байт
Average Speed Dload Средняя скорость передачи данных за всё время загрузки, в байтах в секунду
Average Speed Upload Средняя скорость передачи данных на данный момент, в байтах в секунду
Time Total Ожидаемое время выполнения операции в формате HH:MM:SS для обозначения часов, минут и секунд
Time Current Время, прошедшее с начала передачи, в формате HH:MM:SS для обозначения часов, минут и секунд
Time Left Ожидаемое время, оставшееся до завершения, в HH:MM:SS обозначениях часов, минут и секунд
Curr. Speed Средняя скорость передачи за последние 5 секунд в количестве байт в секунду
При использовании опции --parallel curl может выполнять множество операций одновременно, и тогда вышеупомянутый индикатор выполнения не работает должным образом, так как ему нужно сообщать пользователю о большом количестве операций в одной строке состояния.
DL% Процент завершенной загрузки
UL% Процент загруженных завершенных
DLed Количество загруженных байт
ULed Количество загруженных байт
Xfers Количество завершенных переводов
Live Количество текущих переводов
Total Общее ожидаемое время выполнения всех операций в формате HH:MM:SS для часов, минут и секунд
Current Сколько времени он работает, в формате HH:MM:SS для часов, минут и секунд
Left Ожидаемое время, оставшееся до завершения, в HH:MM:SS обозначениях часов, минут и секунд
Speed Средняя скорость передачи за последние 5 секунд в количестве байт в секунду
Версия
curl --version
curl 8.7.1 (x86_64-pc-linux-gnu) libcurl/8.7.1 OpenSSL/3.0.2 zlib/1.3.1
Release-Date: 2024-03-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS HSTS HTTPS-proxy IPv6 Largefile libz NTLM SSL threadsafe TLS-SRP UnixSockets
В выводе можно увидеть используемые версии библиотек, дату выпуска, поддерживаемые прооколы
Если к номеру версии curl добавлено -DEV, это означает, что версия создана непосредственно из разрабатываемого исходного кода и не является официально выпущенной и одобренной версией.
Код выхода
Если операция прошла по плану curl вернет код 0
Когда curl завершает работу с ненулевым кодом, он также выводит сообщение об ошибке (если не используется --silent).
Ознакомиться со всеми типами ошибок можно в источнике: https://everything.curl.dev/cmdline/exitcode.html
Пользователи также могут создавать собственные сообщения об ошибках с помощью --write-out. Псевдопеременная %{onerror} позволяет задать сообщение, которое будет отображаться только при возникновении ошибок, и предлагает %{errormsg} и %{exitcode} среди всех переменных.
curl --write-out "%{onerror}curl says: (%{exitcode}) %{errormsg}" \
https://curl.se/
Копировать как curl
Большинство современных браузеров позволяют скопировать пользовательский запрос в виде запроса для воспроизведения операции через curl
https://everything.curl.dev/cmdline/copyas.html
В некоторых случаях это может быть полезно
Вывод текста в конце
--write-out или просто -w для краткости, выводит заданный текст и информацию после завершения передачи
curl -w "formatted string" http://example.com/
#Вывод из файла
curl -w @filename http://example.com/
Доступ к доступным переменным осуществляется с помощью %{variable_name} в строке, и эта переменная заменяется на правильное значение. Чтобы вывести обычный % символ, можно использовать %%. Можно вывести новую строку с помощью \n, возврат каретки с помощью \r и пробел с помощью \t.
curl -w "Type: %{content_type}\nCode: %{response_code}\n" \
http://example.com
Доступные переменные для --write-out можно подсмотреть в источнике: https://everything.curl.dev/usingcurl/verbose/writeout.html
#Пример использования --write-out
curl -w "Цепочка сертификатов: %{certs}" https://netbash.ru
HTTP headers
Эта опция также позволяет легко выводить содержимое отдельных заголовков HTTP-ответов
#name — это имя заголовка без учёта регистра
curl -w "Server: %header{server}\n" http://example.com
Output
По умолчанию эта опция выводит выбранные данные в стандартный поток вывода. Если этого недостаточно, можно использовать псевдопеременную %{stderr} для вывода в стандартный поток ошибок, а %{stdout} — для возврата в стандартный поток вывода.
Начиная с версии curl 8.3.0, появилась функция, которая позволяет пользователям отправлять выходные данные в файл: %output{filename}
Если необходимо, чтобы curl добавлял данные в этот файл, а не создавал его с нуля, добавьте к имени файла префикс >>. Например: %output{>>filename}
Источники
Связанные темы
Использование модуля pg_stat_statements в postgresql
Поиск уязвимостей и следов взлома в Linux
Управление планировщиком в Postgresql
Использование wget и curl в Linux
Системные каталоги в Postgresql