Should I use mutually exclusive options on the command line tool

command lineoptionsUtilities

Writing a CLI tool, I'm facing a conundrum.

The tool is supposed to detect faces in images and blur them automatically. However, sometimes only one of those things should be done to allow marking additional faces manually with an external tool. So there are three behaviours I want to support:

  1. Detect faces and blur them in one go
  2. Only detect faces
  3. Only blur faces

My idea of solving this were two mutually exclusive options, something like --only-detect and --only-blur.

However, a coworker suggested that it might make more sense to have --detect and --blur, so that using both options would lead to the same behaviour as using none, but I find this to be less intuitive.

My question now is: Are there any conventions I can follow to make this decision? I found the POSIX Utility Conventions, and they do mention mutually exclusive groups, but nothing that is helpful here.

Best Answer

POSIX just says (regarding mutually exclusive command line options in POSIX utilities):

The use of conflicting mutually-exclusive arguments produces undefined results, unless a utility description specifies otherwise.


Some command line tools have conflicting command line options (such as both a --silent option and a --verbose option). In the case that both options are used when invoking the tool, if allowed, the last parsed option (the one last on the line) usually wins.

The last one of --blur and --detect would be used. The documentation would specify what options were exclusive.

Compare ls -l -C with ls -C -l, for example.


Other tools simply disallow conflicting command line options, giving the user a diagnostic message on the standard error stream and exiting with a non-zero exit code when such a situation occurs.

Your code would error out if both --blur and --detect were used.

This is done in e.g. cut which has conflicting flags -b, -c and -f.


Some tools may provide a different effect depending on what name it is invoked as. So, you could have two names (hard links) for your tool, one called detectface and another called blurface. These would be the exact same binary but the program would determine what name it was invoked as to figure out what operation to perform.

This is common on system where some shell masquerades as both /bin/sh (a POSIX shell) and as itself (e.g. bash on Linux, or ksh on OpenBSD) and that switches to "POSIX sh mode" when invoked as sh, or you might have a compiler that compiles both C and C++ code and switches mode depending on whether it's invoked as cc or c++, etc. (both gcc and clang does this).

Related Question