chmod: removing "x" permission recursively totally borks the permissions

1

I have a folder with some contents (three files and a folder) that look like this:

-rwxr-xr-x 1 max max 14504 2011-05-31 16:55 main.css
-rwxr-xr-x 1 max max  2504 2011-05-31 16:55 reset.css
-rwxr-xr-x 1 max max   916 2011-05-31 16:55 scaffold.css
drwxrwxr-x 3 max max  4096 2011-05-31 16:55 ui-lightness

I want to add group write to all of them and remove the executable status for all users. I do the files first:

$ chmod g+w main.css reset.css scaffold.css 
$ chmod a-x main.css reset.css scaffold.css 
$ ls -l
total 28
-rw-rw-r-- 1 max max 14504 2011-05-31 16:55 main.css
-rw-rw-r-- 1 max max  2504 2011-05-31 16:55 reset.css
-rw-rw-r-- 1 max max   916 2011-05-31 16:55 scaffold.css
drwxrwxr-x 3 max max  4096 2011-05-31 16:55 ui-lightness

So far so good. Now, the ui-lightness folder already has group write, so i just want to remove exe status from it and all the files and subfolders inside.

$ ls -l ui-lightness/
total 40
drwxrwxr-x 2 max max  4096 2011-05-31 16:55 images
-rwxrwxr-x 1 max max 34146 2011-05-31 16:55 jquery-ui-1.8.11.custom.css

$ chmod -R a-x ui-lightness/
chmod: cannot access `ui-lightness/jquery-ui-1.8.11.custom.css': Permission denied
chmod: cannot access `ui-lightness/images': Permission denied

$ ls -l ui-lightness/
ls: cannot access ui-lightness/jquery-ui-1.8.11.custom.css: Permission denied
ls: cannot access ui-lightness/images: Permission denied
total 0
d????????? ? ? ? ?                ? images
-????????? ? ? ? ?                ? jquery-ui-1.8.11.custom.css
$ 

My first instinct is to panic a bit. But, adding the x status back on fixes it!

$ chmod -R a+x ui-lightness/

$ ls -l ui-lightness/
total 40
drwxrwxr-x 2 max max  4096 2011-05-31 16:55 images
-rwxrwxr-x 1 max max 34146 2011-05-31 16:55 jquery-ui-1.8.11.custom.css

Can anyone explain what's going on here? And how i remove the executable status without borking everything? This is in ubuntu 9.10 in case that's relevant.

cheers, max

Max Williams

Posted 2011-06-07T16:17:17.043

Reputation: 2 237

Answers

10

The first parameter to your recursive chmod is the directory itself. You removed x bit on the directory, making it not searchable any more (that's what the x bit does for a directory). Then the chmod program could no longer search inside that directory and you get the permissions errors. try the following instead.

chmod -R a-x ui-lightness/*

Keith

Posted 2011-06-07T16:17:17.043

Reputation: 7 263

ahhh - so directories need to have the x property then? I did not know that. Thanks! – Max Williams – 2011-06-07T16:30:46.677

But, then, if i do chmod -R a-x ui-lightness/*, and there's another subdir inside that, then that subdir will get borked, right? – Max Williams – 2011-06-07T16:31:34.073

6yes. You really should be using find . -type f -exec chmod -x {} \; to select only regular files. – Keith – 2011-06-07T16:37:59.203

9

To remove executable status only for files, use:

$ chmod -R a-x+X ui-lightness/

The +X option is defined (see man chmod) to:

  • set execute permission only if the file is a directory or already has execute permission for some user

So, the lowercase -x option first removes the executable status from all files (and directories, of course), then the uppercase +X option sets it back only for directories.

It has one minor drawback: it sets the executable status to all subdirectories, even to those that didn't have it set prior to the chmod invocation. If that's not what you want, just use Keith's find solution.

charlie

Posted 2011-06-07T16:17:17.043

Reputation: 199

this works perfectly with nested directories! – Hugo Dozois – 2012-10-24T18:27:40.197