Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a project folder which has messy permissions on all files. I've had the bad tendency of setting everything to octal permissions 777 because it solved all non security related issues. Then FTP uploads, files created by text editors etc. has their own set of permissions making everything a mess. I've decided to take myself together and start using the permissions the way they were meant to be used.

I figured 664 was a good default for all my files and folders, and I'd just remove permissions for others on private files, and add +x for executable files.

The second I changed my project folder to 664 however:

$ sudo chmod -R 664 .  
$ ls  
ls: cannot open directory .: Permission denied  

Which makes no sense to me. I have read/write permissions, and I'm the owner of the project folder. The leftmost part of ls -l in my project folder looks like this:

-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 5 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 3 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 4 codemonkey codemonkey ...
drw-rw-r-- 5 codemonkey codemonkey ...

I assume this has something to do with the permissions on the directories, but what?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

The execute bit is needed to traverse a *nix directory. You can't cd into a directory that you don't have execute permissions for, and this affects a number of utilities in non-obvious ways if they need a directory context. Consider:

$ cd /tmp
$ mkdir foo
$ echo baz > foo/bar
$ chmod a-x foo

# You can read the contents of the directory, but ls still complains. 
$ ls foo
ls: cannot access foo/bar: Permission denied
bar

# You can't read the file because you can't enter the directory.
$ cat foo/bar
cat: foo/bar: Permission denied

The reason for all of this is the way that stat() works. Excerpted from man 2 stat:

No permissions are required on the file itself, but — in the case of stat() and lstat() — execute (search) permission is required on all of the directories in path that lead to the file.

The bottom line is that a recursive chmod will rarely do what you expect, and will play havoc with directory read and execute permissions that can lead to unexpected results like yours. Always treat directory permissions separately from file permissions for best results.

share|improve this answer

You need execute permissions on directories.

Consider

sudo find -type d -exec chmod +x {} +

Update: heres my rationalisation of this, apparently odd, use of execute permissions.

Unix (and therefore Linux) pretty much treats everything as files. This extends to disks and to various other devices. it also includes directories.

Traditional Unix filesystems have a set of permissions that apply to files. Therefore the Unix desgners had to find something useful for each permission bit to do when applied to a "file" that wasn't your normal data file.

Let's consider directories. It initially seems reasonable to just use the read-permission to decide whether someone can access the directory - for example to produce a listing of the files in it and their sizes and datestamps etc.

However suppose you want ordinary users to be able to run programs in /usr/local/bin but you don't want them to be able to rummage around in /usr/local to see what's there. If you only have the read-permission you can't prevent this.

So the, otherwise redundant, execute permission was used to control whether your shell is allowed to "traverse" a directory, by which we mean, find out no more that is needed to be able to find and read the details of a subdirectory as part of a path. This allows you to get at the /usr/local directory only so far as is needed to read /usr/local/bin's contents.

So +x on /usr/local means you can run "/usr/local/bin/foo" But +r on /usr/local means you can find out everything that is in /usr/local including who owns it, what permissions each file has, what size it was etc.

The above is based on vague recollection and surmise. It may not be precisely true but I believe it gives a reasonable idea of why "execute" means "able to traverse".

share|improve this answer
    
That makes no sense, but it worked. Why on earth would directories require execute permissions? –  Hubro Apr 13 '12 at 16:35
1  
@Codemonkey Don't bash what you don't understand. How else would you implement access control? –  Daniel Beck Apr 13 '12 at 16:41
    
I'm not bashing anything, just asking why directories needs execute permissions :S –  Hubro Apr 13 '12 at 16:45
1  
@Codemonkey You understand the concept of multi-user systems though, right? There must be some way to prohibit access to directories. That's what execute is used for. That's it. Regarding the naming, well, you're not reading directories either, but list them, and you're not writing them, but add or remove files... –  Daniel Beck Apr 13 '12 at 17:31
    
I assumed directory read permissions would regulate whether or not you could see what's inside it, and write permissions would regulate renaming or deleting it. You can't tell me that's not the logical assumption for someone who hasn't checked. Anyway thanks for the explanation –  Hubro Apr 14 '12 at 0:02

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.