Why do many commands provide the option -q or --quiet to suppress output when you can easily achieve the same thing by redirecting standard output to the null file?
- 15,736
- 4
- 55
- 65
- 1,806
4 Answers
While you can easily redirect in a shell, there are other contexts where it's not as easy, like when executing the command in another language without using a shell command-line. Even in a shell:
find . -type f -exec grep -q foo {} \; -printf '%s\n'to print the size of all the files that contain
foo. If you redirect to/dev/null, you lose bothfindandgrepoutput. You'd need to resort to-exec sh -c 'exec grep foo "$1" > /dev/null' sh {} \;(that is, spawn an extra shell).grep -q foois shorter to type thangrep foo > /dev/null- Redirecting to
/dev/nullmeans the output is still written and then discarded, that's less efficient than not writing it (and not allocate, prepare that output to be written) - that allows further optimisations. In the case of
grepfor instance, since with-q,grepknows the output is not required, it exits as soon as it finds the first match. Withgrep > /dev/null, it would still try to find all the matches. - quiet doesn't necessarily mean silent. For some commands, it means reduce verbosity (the opposite of
-v|--verbose). For instance,mplayerhas a--quietand a--really-quiet. With some commands, you can use-qqqto decrease verbosity 3 times.
- 58,310
- 544,893
-
It's noteworthy that in the
grepman-page both options,-q, and-s, are suggested to be avoided if portability is a concern.grep's early exit is an important optimization, but not all programs with such options can do that;curl -swill still process the whole data (but the 3rd point still applies, thus saving processing time). – Janis Mar 19 '15 at 17:12 -
6@Janis, that would be portability to very old systems. Both
-qand-sare specified by POSIX. If we're to consider systems that old, then mysh -c '...' sh {} \;won't work either (with earlierksh-basedshs). – Stéphane Chazelas Mar 19 '15 at 17:17 -
The man page mentions: USG-style grep also lacked -q but its -s option behaved like GNU grep. - I thought that the difference in behaviour could be an issue. I can't judge about its relevance. – Janis Mar 19 '15 at 17:31
-
I frequently use the -q and --quiet options when I only care about the return code of a command in a script. The reasons noted above are even better examples why. – Mark Stewart Mar 19 '15 at 17:57
-
@StéphaneChazelas: you'd be amazed how (parts of) many systems are still that old... (well, actually, not that many ^^ but there are still some) – Olivier Dulac Mar 19 '15 at 18:28
-
1@Janis - it may be that the GNU
grepmanpage warning of-qportability concerns has another implication. Some readings of POSIXgreppages, when considered alongside Utility Description Defaults might imply that{ grep -q pattern; head; } <seekable_filewould print only the 10 lines following the first match for pattern. GNUgrepwon't do that (not even when combined with its non-POSIX-m1). – mikeserv Mar 20 '15 at 14:45 -
mikeserv, is that a typo in your comment (using a semicolon instead of pipe inbetween the two processes)? – Janis Mar 20 '15 at 16:02
-
@Janis, no he's refering to
{ sed -n 2q; head -n 1; } < seekable_filethat should return the 3rd line as per POSIX (GNU sed doesn't), that is thatsedshould leave the cursor position just after the 2nd line. However, there's not such requirement forgrep -qas POSIX doesn't mandategrepexits upon processing the first matching line. – Stéphane Chazelas Mar 20 '15 at 16:04 -
Stéphane and @Janis - it isn't mandated that it exit, but the Informative section of the
grepspec says it can - and I assume that is because many do - though I don't know of any. The Utility Defaults says that all standard utilities should leave the offset immediately following the last byte read when through. But the weird part about GNUgrep -qisgrep -qm1- where, for whatever reason, though they spec-m1to leave the offset after the matching line, adding the-qnullifies this. – mikeserv Mar 20 '15 at 20:06 -
And actually, Stéphane, I don't know. The
grep -qverbiage (Quiet... Exit with zero status if an input line is selected) doesn't differ terribly fromsed q(Branch to the end of the script and quit without starting a new cycle). When taken in context with mandated exit offset behavior (When a standard utility reads a seekable input file and terminates without an error before it reaches end-of-file, the utility shall ensure that the file offset in the open file description is properly positioned just past the last byte processed by the utility) I should think they'd behave similarly. – mikeserv Mar 20 '15 at 20:43 -
And
curlhas to receive the remainder of the stream for error detection reasons. – waltinator Apr 02 '22 at 01:03
It still allows for the command to put out when It feels it needs to a note to the screen but normally it puts nothing out. with redirecting all to null there is no chance for the output to be seen.
- 141
-
Well, quiet means that no response is expected; it would be unexpected if we'd see output anyway. (In case that there's anyway something "really really really" important to print (in a terminal attached process) a tty/pty device could directly be used by the process. An example for that may be interactive inquiry of a password, or somesuch.) – Janis Mar 19 '15 at 16:57
Although it probably depends on the command, -q would also disable output to stderr. This allows shells that don't easily allow duping stderr to stdout (I'm looking at you, csh & tcsh) to avoid the noise.
Some programs provide a "quiet" option for situations where it may have other meaningful output that you don't want cluttered with status messages. The -q or equivalent would silence all program status output, allowing a pure data stream from, say, tar or gzip.
- 505
Besides all the good responses and points above, it is a best practice to provide an opposite option for every flag. So, if there is -v for verbosity there should be -q for non-verbosity, quiet or silence. (This is not the point of discussion though...) There should be a long option for every short one as well, -q and --quiet.
As in almost everything in our business, there are many ways to get a solution or the same results. Having -q is one of them.
-qto suppress all output. For example, Docker has a command to list images;docker imagesshows a formatted table with a bunch of information, whiledocker images -qoutputs a plain list of image IDs (useful for piping to other commands). – new123456 Mar 19 '15 at 20:42