3

my command looks something like this

find $PATH -name '$FILE.log' > /tmp/file-list.txt

and I keep getting an error message that says

find: illegal option -- n

What am I doing wrong here?

  • 6
    $PATH is a special variable that is meant to contain a colon separated list of directories where to find executables. – Stéphane Chazelas Jun 7 '17 at 16:02
  • 2
    What flavour of linux is that? GNU and busybox find, the most commonly found implementations on systems that have Linux as a kernel don't give that wording for unknown options. – Stéphane Chazelas Jun 7 '17 at 16:03
  • 2
    You'd get that error if you ran find -name with Solaris find (so on Linux, you could get that with the find from the heirloom toolchest (a port of OpenSolaris tools)) – Stéphane Chazelas Jun 7 '17 at 16:06
  • use find $(pwd) if you want current PATH, not $PATH itself – Kiwy Jun 8 '17 at 11:55
19

From that error message, I'd bet that

  • despite your "linux" tag, you're probably not on a Linux-based system as find implementations typically found on Linux-based systems don't use that wording for the errors about unknown options
  • the $PATH variable is unset (which indicates the shell you run that in is probably the Bourne or Korn shell (AT&T implementation)).

That illegal option is the wording typically found on traditional Unix find implementations.

Those traditional implementations also require at least one file argument before you can use a predicate like -name.

Otherwise, -name would be taken as options (as opposed to predicates) if it was the next argument after find.

And -n (the first option in -name which is short for -n -a -m -e) is not a valid find option.

So most likely, the expansion of $PATH results in no argument at all.

That would happen in cases where:

  1. $PATH is unset
  2. $PATH is set to the empty string
  3. $PATH contains only space, tab or newline characters (the default value of $IFS).

Since $PATH is the special variable containing a colon-separated list of directories to look up executables including that find command, we can rule out 3 and most probably 2 (unless there's a find command in the current directory), or otherwise you'd get a find: command not found error.

When $PATH is unset (1 above), in execvp() (as typically used by env or find's -exec predicate for instance) and in some shells (including the Korn and Bourne shell typically found on those traditional OSes), find would be found through a search in a default search path (shells like bash don't do that but set (though not export) $PATH to a default value when it was unset on start-up).

Here, I think you want to:

  • use a different variable name than $PATH to store the directory name (like $dir)
  • be sure to quote your variables
  • use ${dir:-.} if you want to default to the current directory if $dir is empty or unset.
  • (maybe also investigate why the $PATH variable is unset which is highly unusual)

So:

dir=some-dir
find "${dir:-.}" -name "$FILE.log"

Note that it assumes that $dir doesn't start with - and is not otherwise a find operator (like !, (, )) and that $FILE doesn't contain wildcards (*, ?, [...]) (note the use of double quotes instead of single quotes around $FILE.log as I assume you want to find files named something.log where something is the content of $FILE as opposed to files named $FILE.log literally).

  • On Linux, in Bash, when PATH is unset, it does not appear that I can execute any non-builtin commands. Is this different for other shells or for Unix? Also, oddly enough, my version of find (find (GNU findutils) 4.4.2) prints no error when I try find -name foo. – Kyle Strand Jun 7 '17 at 21:35
  • 1
    @KyleStrand about the default search path, see edit. the OP is probably not using bash. As an extension, GNU find treats find -name foo as find . -name foo. If you want to path a file called -name (but that's also the case for find that don't have that extension), you need to use find ./-name -name ... though some implementations support find -f -name -f -type -predicates... (which makes them the only one which can take arbitrary file names as in find -f "$file" -mtime ...). – Stéphane Chazelas Jun 8 '17 at 8:08
  • Wacky! Whatever systems I was using a few years ago must not have had GNU find, because I remember being tripped up by needing to include . when I first started learning to use find. Thanks for the explanation! – Kyle Strand Jun 8 '17 at 16:03
6

$PATH is (usually - unless you have redefined it, but that would break a bunch of things) a colon separated list of directories. find takes a list of directories separated by spaces on the command line:

find /path/to/dir1 /path/to/dir2 -name "$FILE.log"

Note also that single quotes inhibit evaluation of variables by the shell, so you probably need double quotes around $FILE.log as indicated above.

You can convert $PATH to a space-separated list in a number of ways, e.g.:

 echo $PATH | sed 's/:/ /g'

and use command substitution to get the list into your find command:

find $(echo $PATH | sed 's/:/ /g') -name "$FILE.log"
  • 2
    Or just: IFS=:; set -o noglob; find $PATH -name... – Stéphane Chazelas Jun 7 '17 at 16:07

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.