1

I have a Synology NAS, which uses a customised Linux for its OS. Using the find command, I am trying to list the files modified since about 25 days, with some exclusions, within a particular directory.

I noticed that when I use a "*" instead of a "." after find, the result seems different. See the commands below:

find . ! -path "*@eaDir*" -type f ! -iname ".DS_Store" ! -iname "Thumbs.db" -mtime -25

find * ! -path "*@eaDir*" -type f ! -iname ".DS_Store" ! -iname "Thumbs.db" -mtime -25

When I used a ".", I get some output after quite a long time. When I replaced the "." by a "*", I started getting more results very quickly and they were different than when using a ".".

I used ls -al to check whether the results when using a "*" were correct, ie, whether the modified date/time of the files were within the last 25 days and indeed that was the case.

Can anyone tell me why the results are different?

1

The dot signifies the current directory. It is common to use it as the starting PATH for find.

The unadorned asterisk will be expanded by the shell before find executes into the contents of the current directory. This is called "globbing". To see the effect, do:

echo *

Undoubtedly, find * ... isn't what you want to use.

  • Thanks for your reply. But why is the find command taking very long to give some output when using "." compared to when using "*"? Will the results eventually be the same? – EEM RT Feb 27 '17 at 15:49
1

In:

find * ...

as a shell command line, * is a glob that is expanded by the shell to the (lexically sorted) list of non-hidden entries in the current directory (with some shells, that would be only the entries that contain only valid characters as * as a pattern means 0 or more characters).

So, if the current directory contains these entries:

  • .
  • ..
  • .htaccess
  • file.txt
  • -foo-

find will be called with these arguments: find, -foo-, file.txt (and ...). find will most likely complain about that -foo- that is an invalid option or predicate.

Even if you use:

find -- * ...

That won't work properly for files named -anything or ! or (... as -- only tells find to stop looking for options (like -L, -H) not for predicates.

You could use:

find ./* ...

to avoid the problems, but then again, that would omit hidden files, could omit files with invalid characters or break (with arg list too long) if there are a lot of files in the current directory.

With:

find . ...

You only pass . to find. . is the current directory. Then it's find, not the shell that will look for files in there (includes . at depth 0, all the entries except . and .. (other hidden entries included) at depth 1, and all other entries for subdirectories (still excluding . and ..) recursively.

You'd only want to use:

find ./* ...

If you wanted the list of files at depth 1 (and depth 1 only) to be sorted and wanted to exclude hidden files at depth 1 (and again at depth 1 only). Which would be very unlikely.

If you want to exclude hidden files, add a ! -name '.*' Or -name '[!.]*' (though beware of file names with invalid characters, and that would also include the top level directory given to find . which happens to match that pattern).

If you wanted sorting at every level, you'd probably want to resort to zsh and its recursive globbing with glob qualifiers.

The reason you're getting different results is most probably that in find *, find starts by looking (is being told to look) into the first file or directory in the current directory in alphabetical order, and with find ., it looks at . itself but then next the first file or directory in there in a different order (could be the order that entries are stored in the directory, but some find implementations also sort the list by inode number as an attempt to minimise disk head seeks).

BTW, a better way to write your command would probably be:

find . \( -name @eaDir -o -iname .DS_Store -o -iname Thumbs.db \) \
  -prune -o -mtime -25 -type f -print

That is tell find to ignore those directories and their content altogether (not even attempt to look inside them).

  • Thanks a lot Stéphane. Please confirm that your suggested improved command is correct: @eaDir are directories located in different places, while .DS_Store and Thumbs.db are files. Thanks again. – EEM RT Feb 27 '17 at 16:07
  • @EEMRT, yes it's fine to -prune files even if they are not of type directory. Here, because they are selected on the left of the -o, they will not be considered for the right side (for the -mtime -print). – Stéphane Chazelas Feb 27 '17 at 16: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.