curl transfers a URL with an ordered command line: options configure one or
more transfers, and every URL starts a transfer. It supports many protocols;
examples below use HTTP because its request and response controls are common.
Build Requests Deliberately #
Use --request, --header, and --data to state the request. --data
selects POST unless another method is specified. --data-binary @file
preserves the file’s bytes, whereas --data @file has form-oriented behavior.
curl --fail-with-body --show-error --silent \
--request POST \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $token" \
--data-binary @request.json \
--output response.json \
https://api.example.invalid/v1/jobsKeep credentials out of command history where possible: use a restricted
configuration file, a credential helper, or an environment variable consumed
by the service’s supported authentication mechanism. -u user:password can
expose a password in process listings on some systems.
-L follows redirects. Restrict it when the method or credentials must not
reach another origin; inspect redirect behavior with --verbose before
automating it.
Multiple Transfers and URL Globbing #
curl distinguishes global options from per-transfer options. Global options
such as --verbose survive --next; local options such as --header,
--request, and --output reset when --next begins a new operation. Without
--next, local options apply to each following URL until changed, so each
request must have an intentional output and header set.
curl --output first.json https://example.invalid/one \
--next --header 'Accept: text/plain' \
--output second.txt https://example.invalid/twoQuote URL globbing syntax to prevent the shell from expanding it. curl expands
[] ranges and {} lists; #1, #2, and later placeholders in --output
refer to the matching glob components.
curl 'https://example.invalid/page[1-3].json' --output 'page-#1.json'Use --globoff when literal brackets or braces belong to the URL.
Diagnose the Transport Path #
Use --verbose for request, response, proxy, and TLS negotiation details.
Use --write-out to record stable timing and status data without parsing
human-oriented output.
curl --silent --show-error --output /dev/null \
--write-out 'http=%{response_code} dns=%{time_namelookup} connect=%{time_connect} total=%{time_total}\n' \
https://example.invalid/--resolve host:port:address tests a specific address while preserving the
URL host name and TLS SNI. --connect-to redirects a connection more
generally. --proxy selects a proxy, and --noproxy excludes hosts from its
use. Do not use --insecure as a fix for certificate failures: correct the
URL, trust chain, hostname, or local CA configuration.
Capture Results Reproducibly #
--fail-with-body makes HTTP status errors nonzero while preserving an error
response. Check curl’s exit status because a successful TCP exchange does not
make an HTTP request successful. Use --retry only for transfers that are
safe to repeat: retrying an idempotent GET is different from repeating a
payment POST.
For an artifact capture, write headers and body separately, pin the complete URL, and save timing metadata:
curl --fail --show-error --location \
--dump-header artifact.headers \
--output artifact.tar.xz \
--write-out '%{url_effective} %{response_code}\n' \
https://downloads.example.invalid/tool-1.2.3.tar.xz
sha256sum artifact.tar.xzVerify a published checksum or signature; a checksum generated after an untrusted download only records the bytes received.
Comments
Read or comment on GitHub (sign-in required to comment)