Skip to content
Advertisement

Is it possible to reliably nest find -exec commands in linux?

I need to fix permissions on a large number of files from a subset of directories on a large nfs volume.

In building up a solution, I started by using find to get a list of the directories I want:

find . -type d -regex "^./[0-9]*" 

The directories all start with a number.

I can successfully use this to exec a 2nd find. That find gets files that exclude a few filenames I don’t want to process:

find . -type d -regex "^./[0-9]*" -exec find {} -type f ( ! -iname '.*' ! -name 'async.log' ) ;

This all works great and returns the list of files I need to process.

Now to the problem:

What I really want is to use the 2nd find to -exec chmod 644. I have found a way to do this using xargs that seems to work fine. In the examples here I’m using echo just to verify the list of files being returned.

find . -type d -regex "^./[0-9]*" | xargs -I dirname find dirname -type f ( ! -iname '.*' ! -name 'async.log' ) -exec echo {} ;

But what I’d like do is just use -exec with my chained find commands, as it is many times faster than piping the results to xargs, but something goes wrong with the results:

find . -type d -regex "^./[0-9]*" -exec find {} -type f ( ! -iname '.*' ! -name 'async.log' ) ; -exec echo {} ;

When I send output to a file, there is a discrepancy and the nested find command seems to stop before full completion.

When comparing the 2 files, the xargs version has 173125 lines, whereas the nested find command only has 173060 lines.

The last line in the find version shows truncation:

./104/5734c420e70d8.pdf
./104  

I am at a loss to explain this, or come up with a way to debug or workaround the problem. Any ideas on how I might get my find -only solution working?

Advertisement

Answer

I think it should be simplier if you use find only one time.

The following solution will work as long all your directories you want to search are in the same directory.

find {0,1,2,3,4,5,6,7,8,9}* -type f ( ! -iname '.*' ! -name 'async.log' ) -exec chmod 644 {} ;

Search in current directory all directories beginning by a number, exclude file beginning by a dot, exclude file named async.log and apply command chmod 644 to file found.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement