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.