If you use ls -lR
you have to then exclude content from the output, somehow, and then grep
out what you want.
find
is probably quicker. Here's a very quick hack on my machine (the grep
's are ugly, I take no pride in them).
tony@trinity:~$ time ls -lR | grep "tony tony" | grep -vc "rwxr-xr-x"
115668
real 0m3.247s
user 0m1.456s
sys 0m1.808s
tony@trinity:~$ time find ./ -not -perm 755 | wc -l
125185
real 0m0.503s
user 0m0.120s
sys 0m0.380s
tony@trinity:~$ time ls -lR | grep "tony tony" | grep -vc "rwxr-xr-x"
115668
real 0m3.128s
user 0m1.564s
sys 0m1.920s
tony@trinity:~$ time find ./ -not -perm 755 | wc -l
125185
real 0m0.501s
user 0m0.196s
sys 0m0.428s
Some notes:
- I ran both commands twice to remove the chance of difference from caching
- You'll note they return different counts, my quick hack grep isn't good enough to isolate only the relevant files and directory entries.
- The point of this is not to show you a better solution, but to show that
find
is pretty quick compared to raw ls
+ grep
.
There may be faster solutions, such as something in perl
, or a way of making ls
run faster (setting $LANG
? - my tests just showed this knocks a second off the ls
output, you can probably tell ls
not to sort as well, which might help).
Edit: I've just seen your comment where you also say you need to then change the permissions. In which case, find
is absolutely the right answer, because it can do all the work in one go.
find ./ -not -perm 755 -exec chmod 755 {} \;
You should be extremely careful when running that command to make sure you are in the correct location. A safer option would be,
find /actual/full/path -not -perm 755 -exec chmod 755 {} \;
so you avoid changing every file on the system if you're in the wrong place.
Also, you should probably consider softlinks, directories, and non-regular files and modify your find
as a result. So, assuming you only care about files, I would start with,
find /actual/full/path -type f -not -perm 755 -exec chmod 755 {} \;
Lastly, you might want to ask yourself if you're changing the permissions of every file in a directory or set of directories which don't have permissions 755 to 755, then you don't need to do anything complex.
find /actual/full/path -type f -exec chmod 755 {} \;
That will just set them all to 755. It might be a little bit quicker (less logic in choosing which files to update vs. updating millions of files worth of permissions, depends I guess on the number of files which are correct already).
chmod -R
- see my answer. If you know that the non-executable files are only present at a particular depth in the filesystem, you may be able to guidefind
with-mindepth
and/or-maxdepth
- again, give us more context to create a better answer!chmod -R u+rwX,go+rX ./
will recursively ADDrw
(owner) orr
(group,other) perms on all files and directories, and thex
permission for owner,group, and other on all directories (if you want it to set it to exactly rX or rwX, use=
rather than+
). Note the capitalX
rather than lowercasex
in thechmod
command - that sets the execute bit on directories but not other kinds of files.+X
will also add the corresponding execute permission to any file that has any one of the three execute bits already set.inotify
or similar interface, to only examine files as they are created or changed.