The precedence of command options

commandcommand lineoptionsrm

I know that rm -f file1 will forcefully remove file1 without prompting me.

I also know that rm -i file1 will first prompt me before removing file1

Now if you execute rm -if file1, this will also forcefully remove file1 without prompting me.

However, if you execute rm -fi file1, it will prompt me before removing file1.

So is it true that when combining command options, the last one will take precedence ? like rm -if, then -f will take precedence, but rm -fi then the -i will take precedence.

The ls command for example, it doesn't matter if you said ls -latR or ls -Rtal.

So I guess it only matters when you have contradictory command options like rm -if, is that correct?

Best Answer

When using rm with both -i and -f options, the first one will be ignored. This is documented in the POSIX standard:

    -f
       Do not prompt for confirmation. Do not write diagnostic messages or modify
       the exit status in the case of nonexistent operands. Any previous
       occurrences of the -i option shall be ignored.
    -i
       Prompt for confirmation as described previously. Any previous occurrences
       of the -f option shall be ignored.

and also in GNU info page:

‘-f’
‘--force’

    Ignore nonexistent files and missing operands, and never prompt the user.
    Ignore any previous --interactive (-i) option.

‘-i’
    Prompt whether to remove each file. If the response is not affirmative, the
    file is skipped. Ignore any previous --force (-f) option.

Let's see what happens under the hood:

rm processes its option with getopt(3), specifically getopt_long. This function will process the option arguments in the command line (**argv) in order of appearance:

If getopt() is called repeatedly, it returns successively each of the option characters from each of the option elements.

This function is typically called in a loop until all options are processed. From this functions perspective, the options are processed in order. What actually happens, however, is application dependent, as the application logic can choose to detect conflicting options, override them, or present an error. For the case of rm and the i and f options, they perfectly overwrite eachother. From rm.c:

234         case 'f':
235           x.interactive = RMI_NEVER;
236           x.ignore_missing_files = true;
237           prompt_once = false;
238           break;
239 
240         case 'i':
241           x.interactive = RMI_ALWAYS;
242           x.ignore_missing_files = false;
243           prompt_once = false;
244           break;

Both options set the same variables, and the state of these variables will be whichever option is last in the command line. The effect of this is inline with the POSIX standard and the rm documentation.

Related Question