Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was doing a mass recursive change of permissions of some files that I had migrated to a unix system. I changed them to ug+rw, but then I found that I could not traverse subdirectories. I looked at the man page for chmod and didn't see any explanation for excluding directories, so I googled a little and found that people used find to recursively change the permissions on directories to 'execute' for user and group. I did that and then I could look into them.

But it seemed to me that I should be able to be able to do this find chmod -- to recursively change the files to read/write but not make the directories untraversable. Have I done this the 'right' way or is there a simpler way to do it?

share|improve this question
up vote 10 down vote accepted

The better solution should be

chmod -R ug=rwX,o=rX /path

where the capital X means: set execute bit if

the file is a directory or already has execute permission for some user

(quoted from chmod man page).

Or also, if you want to use find

find /path \( -type f -exec chmod ug=rw,o=r   {} + \) -o \
           \( -type d -exec chmod ug=rwx,o=rx {} + \)
share|improve this answer
    
I used the wide open for everyone version of this command for my USB hard drive: chmod -v -R ugo=rwX /path Thanks! – The Dude Sep 10 '14 at 14:08
    
Evidently there is no way without using find to set all file permissions to 600 and all directory permissions to 700. (I arrived here through my googlings on the subject.) If that can be done with a single chmod -R command, feel free to correct me. – Wildcard Jan 22 at 22:59
    
@Wildcard: not exactly, the command chmod -R u=rwX,go= /path does almost what you want: it sets all dirs to 700 and all files to 600 or 700, depending on if the execution bit is already set or not, and I think this is the right thing to do. – enzotib Jan 23 at 8:14
1  
@enzotib, yes—almost, but not quite. In my case I want to disable the execution bit for all files (but not directories of course) regardless of whether they are scripts or binaries or whatever. So the find command you wrote was very helpful as a template. :) – Wildcard Jan 23 at 9:10
    
@Wildcard what about removing the execute bit first, recursively, then add it back only to directories using the above command? – Michael Mar 3 at 18:06

Using find is the 'right' way, and the only programmatic way, although there are variations:

find . -type f -exec chmod ug+rw {} +  # "+" may not be on all systems

or

find . -type f -print0 | xargs -r0 chmod ug+rw  # similar to the -exec + functionality

or the slowest:

find . -type f -exec chmod ug+rw {} \;  # in case xargs is not installed

Each of these selects a file (not directory, not symlink) and applies the chmod command on it. The first two reduce the number of calls to chmod by appending the file to the end of an internal command line each time until a maximum is reached (often 10), then calls the command and starts rebuilding a new command. The last statement spawns a new process for each file, so it is less efficient.

share|improve this answer

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.