7

I have an installation script that unzips a directory, then recursively chmods its contents.

I'm surprised it takes almost 10 times the time it takes to unzip, to run the following two commands:

find $dir -type f -exec chmod a+r "{}" \;
find $dir -type d -exec chmod a+rx "{}" \;

Am I doing something wrong, is there a faster way to change the chmod of all files and directories?

BenMorel
  • 4,507
  • 10
  • 57
  • 85
  • 1
    One trick I use is just to do a chmod -R on everything (files & directories) then run the find to fix up the directories – jeffatrackaid May 20 '13 at 16:58
  • 3
    You are doing `-exec chmod a+r "{}" \;` try `chmod a+r "{}" +` instead. The first will run the command chmod once for every directory. The later command will run chmod a few times, with a list of directories as options (ie `chmod dir1 dir2 dir3 dir4`). This means far few processes are created. – Zoredache May 20 '13 at 17:01
  • Could the downvoter/closer explain what's wrong with this question? – BenMorel May 20 '13 at 17:01
  • I didn't downvote, but your question probably would have been more appropriate over on unix.stackexchange.com. – Zoredache May 20 '13 at 17:02
  • @Zoredache Woah, the `+` trick is blazing fast! Can you add your comment as an answer? – BenMorel May 20 '13 at 17:08
  • You can try `-exec chmod a+r "{}" + \;` too, that should be faster. Duh, I'm too slow. – ott-- May 20 '13 at 17:11
  • @jeffatrackaid no fixup needed, see [mgorven’s answer](http://serverfault.com/a/509373/82614) – törzsmókus Dec 16 '16 at 11:44

4 Answers4

15

You can get rid of the find commands by using chmod's X flag:

execute/search only if the file is a directory or already has execute permission for some user (X)

This allows you to set the same permissions on files and directories, with directories additionally being executable, with a single command:

$ chmod -R a+rX $dir
mgorven
  • 30,615
  • 7
  • 79
  • 122
5

You could do the following (assumming Linux):

cd $dir
chmod -R a+r .
find . -type d -print0 | xargs -0 chmod a+x

This should be much faster than the combination of the two commands you indicated in your question.

mdpc
  • 11,856
  • 28
  • 53
  • 67
2

Use tar instead. Specifically with the -p, --preserve-permissions, --same-permissions flag.
You won't can't directly zip it, but -z, --gzip, -j, --bzip2 or -J, --xz ought to work well enough. If you really must have zip it's only a | away.

84104
  • 12,905
  • 6
  • 45
  • 76
0

Given your command, I'm thinking you are spending time waiting for find not chmod.

Try:

chmod -R a+r $dir

The "-R" means recursive

When you run the unzip and other commands preface them with

time

To get a measurement of the time spent for the various commands.

John Kloian
  • 142
  • 3
  • Thanks, but unfortunately this solves only half of the problem (I need a different `chmod` for directories). – BenMorel May 20 '13 at 17:09