3

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.

rld.
  • 261

2 Answers2

2

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 09 '17 at 00:35
-1

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 (!).

Michael
  • 39