In this answer, what is the use of -! in find?

Consider the following code:

find . -type l -! -exec test -e {} \; -print

This alternative seems to do the same exact thing:

find . -type l ! -exec test -e {} \; -print

It appears the -! works like !, meaning negation of the following expression. Which makes sense. But why not just ! then? I can't seem to find any documentation on such syntax.

  • 4
    I think it's a mistake (and generous interpretation by, I presume, GNU find). Mar 8 '17 at 5:22
  • It is certainly not the case for the find in NetBSD
    – Fox
    Mar 8 '17 at 13:40

Accepting -! in addition to the standard ! (and likewise for other punctuation operators: (, ), and the GNU-specific ,) is a quirk of the command line parser of GNU find. The code just happens to be slightly easier to write if it doesn't reject -! and the like as ill-formed. Since -! would otherwise be an error, there's no harm in accepting it. The POSIX standard doesn't say anything about what -! means: as far as the standard is concerned, it's an implementation-defined predicate, which implementations are free to use to mean whatever they want.

Here's an overview of how the code in GNU find works:

  • The parser code contains a list of operators. Operators are stored without their leading -, to make the code slightly smaller and faster.
  • The command line parser calls looks_like_expression to determine whether an argument looks like a predicate. Predicates begin with -, except for the single-punctuation-character operators.
  • Once the predicate has been determined, find_parser ignored the leading - if there is one. This is the point where the distinction between ! and -! is lost.

looks_like_expression or find_parser could reject - followed by a punctuation character. But either way it would require additional code for no real benefit.

  • Wow, good one. That's kind of what I expected. Certainly kudos for digging that up and explaining in detail, though.
    – rld.
    Mar 9 '17 at 0:35

The -! is negagting the expression "-type l" which means in your example "List all entries which are not a link".

-type l will become only true, if the "file" is a link, -! will negate it.

From find manpage:

The POSIX standard specifies parentheses `(', `)', negation `!' and the `and' and `or' operators ( -a, -o).

The minus is the seperator for the options. Like in any other command, every option is seperated by a minus (e.g. ls -l). It is not reversing the meaning of the Exclamation mark (!).

  • 5
    I think you've missed the point of the question. The OP knows about ! and they are asking why -! is also valid given that it's not documented anywhere.
    – roaima
    Mar 8 '17 at 7:42
  • This isn't even right: ! negates the following expression, not the preceding one. Mar 8 '17 at 22:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.