2

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?

4
  • 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. Commented Apr 26, 2013 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. Commented Apr 26, 2013 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). Commented Apr 26, 2013 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)? Commented Apr 26, 2013 at 19:48

1 Answer 1

4

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.