diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc index 6e7f0aafa6..c5f99477fa 100644 --- a/docs/cmdline-opts/Makefile.inc +++ b/docs/cmdline-opts/Makefile.inc @@ -181,6 +181,7 @@ DPAGES = \ ntlm.md \ oauth2-bearer.md \ output-dir.md \ + out-null.md \ output.md \ parallel-immediate.md \ parallel-max.md \ diff --git a/docs/cmdline-opts/out-null.md b/docs/cmdline-opts/out-null.md new file mode 100644 index 0000000000..58e5508cdc --- /dev/null +++ b/docs/cmdline-opts/out-null.md @@ -0,0 +1,26 @@ +--- +c: Copyright (C) Daniel Stenberg, , et al. +SPDX-License-Identifier: curl +Long: out-null +Help: Discard response data into the void +Category: output +Added: 8.16.0 +Multi: boolean +See-also: + - output + - remote-name + - remote-name-all + - remote-header-name +Example: + - "https://example.com" --out-null +--- + +# `--out-null` + +Discard all response output of a transfer silently. This is the more +efficient and portable version of + + curl https://host.example -o /dev/null + +The transfer is done in full, all data is received and checked, but +the bytes are not written anywhere. diff --git a/docs/cmdline-opts/output.md b/docs/cmdline-opts/output.md index 48360a4989..e07c0756a6 100644 --- a/docs/cmdline-opts/output.md +++ b/docs/cmdline-opts/output.md @@ -9,6 +9,7 @@ Category: important output Added: 4.0 Multi: per-URL See-also: + - out-null - remote-name - remote-name-all - remote-header-name @@ -56,6 +57,10 @@ Or for Windows: curl example.com -o nul +Or, even more efficient and portable, use + + curl example.com --out-null + Specify the filename as single minus to force the output to stdout, to override curl's internal binary output in terminal prevention: diff --git a/docs/options-in-versions b/docs/options-in-versions index a9ef8db047..bf34e76f2c 100644 --- a/docs/options-in-versions +++ b/docs/options-in-versions @@ -145,6 +145,7 @@ --ntlm 7.10.6 --ntlm-wb 7.22.0 --oauth2-bearer 7.33.0 +--out-null 8.16.0 --output (-o) 4.0 --output-dir 7.73.0 --parallel (-Z) 7.66.0 diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index da0c8f55f4..ce55d5d8e8 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -141,6 +141,9 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) intptr_t fhnd; #endif + if(config->out_null) + return bytes; + #ifdef DEBUGBUILD { char *tty = curl_getenv("CURL_ISATTY"); diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index bd32ab2d42..abce5cc419 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -340,6 +340,7 @@ struct OperationConfig { BIT(rm_partial); /* on error, remove partially written output files */ BIT(skip_existing); + BIT(out_null); /* WRITEFUNCTION into the void */ }; struct GlobalConfig { diff --git a/src/tool_getparam.c b/src/tool_getparam.c index f45959068f..700e213947 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -224,6 +224,7 @@ static const struct LongShort aliases[]= { {"ntlm", ARG_BOOL, ' ', C_NTLM}, {"ntlm-wb", ARG_BOOL|ARG_DEPR, ' ', C_NTLM_WB}, {"oauth2-bearer", ARG_STRG|ARG_CLEAR, ' ', C_OAUTH2_BEARER}, + {"out-null", ARG_BOOL, ' ', C_OUT_NULL}, {"output", ARG_FILE, 'o', C_OUTPUT}, {"output-dir", ARG_STRG, ' ', C_OUTPUT_DIR}, {"parallel", ARG_BOOL, 'Z', C_PARALLEL}, @@ -1313,6 +1314,7 @@ static ParameterError parse_output(struct OperationConfig *config, err = getstr(&url->outfile, nextarg, DENY_BLANK); url->useremote = FALSE; /* switch off */ url->outset = TRUE; + config->out_null = FALSE; /* switch off --out-null */ return err; } @@ -1833,6 +1835,9 @@ static ParameterError opt_bool(struct OperationConfig *config, return PARAM_LIBCURL_DOESNT_SUPPORT; togglebit(toggle, &config->authtype, CURLAUTH_NTLM); break; + case C_OUT_NULL: /* --out-null */ + config->out_null = toggle; + break; case C_BASIC: /* --basic */ togglebit(toggle, &config->authtype, CURLAUTH_BASIC); break; diff --git a/src/tool_getparam.h b/src/tool_getparam.h index 50625d1441..47e87eab92 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -167,6 +167,7 @@ typedef enum { C_NTLM, C_NTLM_WB, C_OAUTH2_BEARER, + C_OUT_NULL, C_OUTPUT, C_OUTPUT_DIR, C_PARALLEL, diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index beb034eeaf..8572250b5c 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -442,6 +442,9 @@ const struct helptxt helptext[] = { "OAuth 2 Bearer Token", CURLHELP_AUTH | CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | CURLHELP_LDAP}, + {" --out-null", + "Discard response data into the void", + CURLHELP_OUTPUT}, {"-o, --output ", "Write to file instead of stdout", CURLHELP_IMPORTANT | CURLHELP_OUTPUT}, diff --git a/tests/http/testenv/curl.py b/tests/http/testenv/curl.py index 2f19eb3744..26d2dd716c 100644 --- a/tests/http/testenv/curl.py +++ b/tests/http/testenv/curl.py @@ -587,7 +587,7 @@ class CurlClient: extra_args = [] if no_save: extra_args.extend([ - '-o', '/dev/null', + '--out-null', ]) else: extra_args.extend([ @@ -636,7 +636,7 @@ class CurlClient: if extra_args is None: extra_args = [] extra_args.extend([ - '-X', 'DELETE', '-o', '/dev/null', + '-X', 'DELETE', '--out-null', ]) if with_stats: extra_args.extend([ @@ -702,7 +702,7 @@ class CurlClient: extra_args = [] if no_save: extra_args.extend([ - '-o', '/dev/null', + '--out-null', ]) else: extra_args.extend([