Bleakley
Bleakley

Reputation: 733

Passing a command to 'find -exec' through a variable does not work

given a directory $HOME/foo/ with files in it.

the command:

find $HOME/foo -type f -exec md5deep -bre {} \;

works fine and hashes the files.

but, creating a variable for -exec does not seem to work:

md5="md5deep -bre"

find $HOME/foo -type f -exec "$md5" {} \;

returns: find: md5deep -bre: No such file or directory

why?

Upvotes: 2

Views: 1519

Answers (4)

Michail Alexakis
Michail Alexakis

Reputation: 1585

I have found the syntax for find -exec a bit weird (with several pitfalls as the ones @codeforester has mentioned).

So, as an alternative, i tend to separate the search part from the action part by piping the output of find (or grep) to a proper xargs process.

For example, i find it more readable (-n1 for using exactly 1 argument per command):

find $HOME/foo -type f | xargs -n1 md5deep -bre

Upvotes: 0

markling
markling

Reputation: 1384

Better still, make the whole -exec statement optional:

md5Cmd=( -exec md5deep -bre {} \; )
find "$HOME/foo" -type f "${md5Cmd[@]}"

Upvotes: 0

codeforester
codeforester

Reputation: 42999

Since you are enclosing your variable in double quotes, the entire string gets sent to find as a single token following -exec and find treats it as the name of the command. To resolve the issue, simply remove the double quotes around your variable:

find "$HOME/foo" -type f -exec $md5 {} \;

In general, it is not good to store commands in shell variables. See BashFAQ/050.

Upvotes: 3

chepner
chepner

Reputation: 531135

Use an array.

md5Cmd=(md5deep -bre)

find "$HOME/foo" -type f -exec "${md5Cmd[@]}" {} \;

Upvotes: 3

Related Questions