0

It is so strange that sometimes the following pattern of -name in find could unexpectedly search all the corresponding filenames successfully. By rights, it could only search one corresponding filename in the current directory via the shell parse (not find utility that without quotation).

find /tmp -type f -name *.txt

/tmp/amp_iostat.txt
/tmp/awrrpt_1_7950_7973.txt
/tmp/oplanlog/osys/2014-07-01-12-26-28/log.txt
/tmp/oplanlog/osys/2014-07-01-13-15-33/log.txt
/tmp/oplanlog/osys/2014-07-01-13-17-58/log.txt
/tmp/oplanlog/osys/2014-07-01-13-30-27/log.txt
/tmp/oplanlog/osys/2016-10-27-19-38-50/log.txt
/tmp/pms2_20170427.txt
/tmp/pmsdb1_20170622.txt
/tmp/pmssh1_20160728.txt
/tmp/pmssh1_20160831.txt
/tmp/pmssh1_20161227.txt
/tmp/pmssh1_20170328.txt
/tmp/pmssh1_20170523.txt
/tmp/pmssh1_20170727.txt
/tmp/pmssh1_20170822.txt
/tmp/pmssh2_20170328.txt
/tmp/pmssh_20170119.txt
/tmp/pmssh_20170220.txt
/tmp/sgpms_20140717_1736_summary.txt
/tmp/sgpms_20140717_1736_trace.txt
/tmp/sgpms_20140717_1737_summary.txt
/tmp/sgpms_20140717_1737_trace.txt
/tmp/sgpms_20140717_1739_summary.txt
/tmp/sgpms_20140717_1739_trace.txt
/tmp/sgpms_20140717_1743_summary.txt
/tmp/sgpms_20140717_1743_trace.txt
/tmp/sgpms_20140717_1749_summary.txt
/tmp/sgpms_20140717_1749_trace.txt
/tmp/sgpms_20140717_1751_summary.txt
/tmp/sgpms_20140717_1751_trace.txt

find /tmp -type f -name *.txt|wc -l
      31
2
  • 1
    You're in an empty directory/one with no .txt files. Is that the question? – Michael Homer Dec 2 '17 at 9:00
  • Yes, there is just by chance no any .txt files under the current directory(/)! – lylklb Dec 2 '17 at 10:22
4

Without any quoting *.txt is subject to pathname expansion (aka filename expansion). This happens in the current working directory (CWD). If the CWD contains any files with extension 'txt' then before calling find the shell replaces the *.txt parameter with the matching filenames and your command becomes something like this:

find /tmp -type f -name file1.txt file2.txt file3.txt ...

There are at least three results you can then get depending on whether the expansion returns...

  • ...multiple files: you will get an error
  • ...one file and its name matches a filename in the path(s) you are running find against: the -name test will match just that one file
  • ...one file and it matches no files in the searched path(s): -name will match nothing

On the other hand if the CWD does not contain any txt files then *.txt is passed to find and it behaves exactly the same as if you quoted it.

Moral: when using find always put quotes around patterns that contain globs unless you actually want the pathname expansion to occur (rarely would you see this done intentionally for the -name option).

5
  • Yes, you are right! I have already tested & verified the result! But why the find utility still always starts to search files from the current directory(/) regardless of specific searching path(/tmp) – lylklb Dec 2 '17 at 10:16
  • Pathname expansion doesn't have anything to do with find. It's a function of the shell and it happens before find runs. So the expansion occurs against your CWD. But find will still be operating against the path you pass to it. You should not be seeing something different. – B Layer Dec 2 '17 at 10:21
  • In fact, I mean that the find utility should be able to avoid & filtrate this unnecessary disturb from the current directory, or why not!? – lylklb Dec 2 '17 at 10:36
  • Because, like I said, this all happens before find starts...it has no way of knowing that you passed it *.txt. I made a small update to my answer to point out that shell replaces the param. – B Layer Dec 2 '17 at 10:37
  • Yes, thanks to your wonderful explanations!! – lylklb Dec 2 '17 at 10:52

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.