By now you should be familiar with running shell commands.

If you are fortunate, you should have noticed a pattern in how you provide them.

The general themes are:

  1. Short options of a single character after a hyphen,

    1. Possibly followed by a second argument as a value to the argument, or the value to the option immediately following.

      So -ofoo is equivalent to -o foo.

    2. Multiple short options that don't take a value argument grouped into the same command.

      So -abc and -a -b -c are equivalent.

    When combining short option groups and short options with value arguments, you can provide as many no-value options in the same command as you like but the string after the first option with a value becomes the value for that option.

    So -vvofoo is equivalent to -v -v -o foo, and if you want to provide multiple -o options, the shortest way to express that is -vvofoo -obar.

  2. Long options starting with two hyphens.

    1. Value-less options such as --foo, often paired with a --no-foo.
    2. Options with values, either with the value as a separate command-line argument, or separated by an equals, so --foo=bar is equivalent to --foo bar.
  3. Any number of positional arguments after any number of option arguments.

    1. Traditional posix behaviour has the first non-option argument being the last option with the rest being interpreted as positional arguments.

      So with --foo bar baz --qux is not equivalent to --foo bar --qux baz.

    2. The usual GNU behaviour is to scan all the options to look for options and letting you intersperse positional arguments with optional.

      So baz --foo bar is equivalent to --foo bar baz.

    You can force posix behaviour by setting the POSIXLY_CORRECT environment variable.

    You can force arguments to be positional with the magic -- argument, so --foo bar -- baz --qux is not equivalent to --foo bar baz --qux.

    If you are writing shell scripts -- is very useful, since if you are providing values from external sources you should use -- to prevent it interpreting your positional arguments as extra options which may change the behaviour.

    Try to remember this, otherwise if you have a file called -f in a directory, alias rm='rm -i' won't prevent you from accidentally removing things if you run rm * instead of rm -- *.

  4. Arguments split into comma-separated sub-options.

    You may have noticed that few tools accept multiple values per option, the traditional work-around for this is to provide only one value argument, but split that up with comma (,) or colon (:) characters.

    If it is comma separated, it may also be sub-option KEY[=VALUE] pairs.

    If you are unfortunate, the values may be file paths, which is a problem, because file paths may contain colons.