Take the 2-minute tour ×
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.

I've got a perl script which systematically changes permissions. The first thing the script does is remove all permissions. It does this by calling chmod(from perl). I did this as I found the set guid bit wouldn't clear unless I explicitly cleared it:

system('find',
        $topdir,
        '-exec', 'chmod', 'u-swrx,g-swrx,o-swrx', '{}', ';'
);

I set different permissions for groups and directories. Using find, I call it from perl as follows (in this case for directories):

system(
    'find',
    $topdir,
    '-type', 'd',
    '-exec', 'chmod', 'g=rx', '{}', ';'
  );

Now even though I only set rx, when I check file permissions after the script has finished executing, the scripts appear to have rwx. Is there something I should look out for, as I don't quite follow why this is happening; I don't explicitly set it anywhere. I do set ACLs as well, but they all behave as expected. The only thing of note I see when I check with getfacl is mask::rwx and default:mask::rwx. Could that be what is causing the problem?

share|improve this question
1  
As a note, there's a native perl chmod, and a core File::Find module that works recursively much like find. Kind of tidier and probably more flexible, etc. Plus File::Find is worth learning how to use. –  TAFKA 'goldilocks' Apr 26 '13 at 18:35
2  
As you call chmod for all objects anyway (first find call) it makes sense to leave out find completely and use chmod -R ... instead (unless you are not root but then you should call find with the option -depth). The second call can be a lot faster by using -exec + (if your find supports that). For debugging I recommend that you call chmod (via find -name) for a single file and run the perl script through strace. That should tell you what happens at the system level. –  Hauke Laging Apr 26 '13 at 18:36
1  
Try doing the chmod g=rx file for some file, and look what happens. Perhaps you aren't allowed to change permissions (you can change them only on your objects, unless you are root). –  vonbrand Apr 26 '13 at 19:00
1  
And just to be sure, you're not trying this on FAT32 or similar (i.e., a filesystem which doesn't support permissions)? –  derobert Apr 26 '13 at 19:48
add comment

1 Answer

Look at the error output: you should be seeing find: `…' Permission denied errors. The first thing you do is remove all access permissions from $topdir, which prevents recursing further into it. None of the chmod commands you expect are executed except for the very first one.

If you want to remove the permission to access all the directories in a tree, you need to do it from the inside out. Otherwise, once you've cut yourself off from the parent directory, you can't recurse into it any more.

system('find',
        $topdir,
        '-depth',
        '-exec', 'chmod', 'u-swrx,g-swrx,o-swrx', '{}', ';'
);

Since you're using Perl, use File::Find instead of calling the external program find. Use the finddepth function to get the right traversal order.

It seems pointless to do two traversals. Instead, do a single traversal and directly set the file permissions to what you want, e.g. chmod 0750 or whatever it should be. Using File::Find will give you greater flexibility to e.g. treat directories and regular files differently.

share|improve this answer
add comment

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.