Find in Bash scripting: paths must precede expression

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, August 08, 2011

Follow me on Twitter as @mattiasgeniar

If you’re trying to use the find binary in your Bash Scripts, and are creating your parameters in your scripts, you can run into the following problem when executing it.

/usr/bin/find: paths must precede expression
Usage: /usr/bin/find [-H] [-L] [-P] [path...] [expression]

Even though if you copy/paste the find-string into your current shell and execute it, the find command works just fine. This can happen when you’re nesting expressions like such:

#!/bin/bash
# Create your variable
FIND_EXEC="find '/home/mattias/data/' -not \( \( -path '/home/mattias/data/production/*' -prune \) -o \( -path '/home/mattias/data/testing/*' -prune \) \)"
# Run it
$FIND_EXEC

When trying to run that through a bash-shell, you’ll get the following output.

# ./testFind.sh
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

Even though if you execute the entire find command, it works like a charm. The problem lies within Bash’ way of escaping data, which gets complicated when your find command already has escaped data in it. If you still want to use the find variable you just created ($FIND_EXEC in my example), you can run it with the eval keyword in front of it.

#!/bin/bash
# Create your variable
FIND_EXEC=">find '/home/mattias/data/' -not \( \( -path '/home/mattias/data/production/*' -prune \) -o \( -path '/home/mattias/data/testing/*' -prune \) \)"

# Run it, with eval this time
eval $FIND_EXEC

Which works just fine when you run it.

# ./testFind.sh
/home/mattias/data/
/home/mattias/data/testFind_ignore.txt
/home/mattias/data/includes
...

That’s a line I won’t soon forget.



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.