Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Here's a command that works fine:

echo Blah: `stat -c %a .`

Is it possible to get find -exec to execute this same thing for every file found, with {} in place of .?

share|improve this question
1  
Backticks can't work there because they are evaluated once before find is even executed and the result is used as a static parameter for find. –  Sven Feb 8 '11 at 13:43

4 Answers 4

up vote 4 down vote accepted

The best way to do that is to use positional parameters. And $() is preferred for command substitution ove backticks because it's more readable (isn't confused with single quotes) and can be easily nested without having to do a lot of escaping.

find . -exec bash -c 'echo Blah: $(stat -c %a "$@")' _ {} \;

The underscore is a placeholder for $0.

share|improve this answer

What for?

find ... -printf 'Blah: %m\n'

Or use bash -c if you really have to:

 find . -exec bash -c 'echo Blah: `stat -c %a {}`' \;
share|improve this answer
    
Thanks for solving my immediate problem, but I'm still curious to know if backticks can be used as described. Just to widen my horizons. –  romkyns Feb 8 '11 at 13:35
    
You'd have to invoke the shell via bash -c or similar. –  Ignacio Vazquez-Abrams Feb 8 '11 at 13:38

The only way to use them (AFAIK) is to place them in a bash script file and use the script in -exec. Same thing with $()

share|improve this answer

Don't forget xargs ! Your example would invoke a new shell process for each file found.

I would prefer this:

find ... | xargs stat -c "Blah: %a"

find outputs a list of everything found, xargs reads a list of arguments on stdin and executes its parameter with those arguments on the command line, building as long a command line as possible. It works because stat, as most other proper commands/programs do, take any number of parameters. (compare ls, rm and echo for instance)

If you think it's absolutely neccessary to launch a new process for each file, use xargs -n 1 to only pass 1 parameter to each command. That way you can mimick the inefficient methods like this:

find ... | xargs -n 1 stat -c "Blah: %a"

(Try it on a big filesystem on a slow computer and time the differences!)

share|improve this answer
    
I appreciate the effort, but I need those backticks. Obviously my example is simplified and uses echo + stat; the real script uses neither echo nor stat, so your trick of putting them together into stat's format string doesn't help at all. –  romkyns Feb 8 '11 at 20:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.