====== Selective CHMOD in Perl with pattern matching ====== {{tag>perl debian}} Simple problems can become quite tricky to solve. Recently, I had to give FTP access to a large folder in which I had some private information. I did not want to reorganize the folder just because of this access, and I was already using group permission that I couldn't change. [[http://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it|TIMTOWTDI]] applied, I choosed to created a small perl script that would check the name of a folder/file and, if this name matches some predefined pattern, would apply a specific chmod permission to it. For example: pattern is "doh" and attached permission is "740". In the list below, directory **todohpoh** and file **azodihazodihdoh** will match and permission **740** will be applied to them. $ ls -al /tmp total 64 drwxrwxrwt 13 root root 12288 oct 28 15:57 . drwxr-xr-x 25 root root 4096 fev 16 2009 .. -rw-r--r-- 1 julien julien 0 oct 28 15:57 azodihazodihdoh -rw-r--r-- 1 julien julien 2513 oct 13 14:30 dokulist drwxr-xr-x 2 julien julien 4096 oct 27 18:18 prv drwxr-xr-x 2 alfresco hugetlb 4096 oct 27 10:46 sv728.tmp drwxr-xr-x 2 julien julien 4096 oct 28 15:57 todohpoh drwxrwxrwt 2 root root 4096 oct 12 07:58 .X11-unix drwxr-xr-x 2 julien julien 4096 oct 27 18:19 xxXXprvfdz drwxr-xr-x 2 julien julien 4096 oct 27 18:19 xxzzzazzdazd * __Program__: chmod_selected_folders.pl * __OS__ : Debian Lenny - Linux 2.6.26-1-686 #1 SMP * __Tested on__: v5.10.0 built for i486-linux-gnu-thread-multi #! /usr/bin/perl -w use strict; # julien vehent - oct. 2009 # browse a list of folder and change the permission # according to a defined list of patterns and perms # perm_list contain pattern + associated chmod perm (user|group|others) # the first pattern that matches is the one applied # "default" is mandatory and applied when no pattern match the entry # my %perm_list = ( "prv" => "770", "default"=> "775" ); my $verbose = 0; sub check_recursively { my $folder_name = $_[0]; print "entering $folder_name\n"; # open folder and loop on each entry opendir my($folder), $folder_name or die "Couldn't open $folder_name: $!\n"; for my $entry (readdir($folder)) { if(($entry eq ".") or ($entry eq "..")) { next; } my $entry_chmoded = 0; my $entry_full_path = $folder_name."/".$entry; # check entry with all patterns, except default foreach my $pattern (keys %perm_list) { # entry matches pattern, apply corresponding chmod and mark entry if (($entry =~ /$pattern/) and ($pattern ne "default")) { print "$pattern matches -> chmod $perm_list{$pattern} $entry_full_path\n" if $verbose == 1; system("chmod $perm_list{$pattern} \"$entry_full_path\""); $entry_chmoded = 1; } } # entry didn't match any pattern, apply default permission if($entry_chmoded == 0) { print "default -> chmod $perm_list{'default'} $entry_full_path\n" if $verbose == 1; system("chmod $perm_list{'default'} \"$entry_full_path\""); } #if entry is a folder, go visit it if ((-d $entry_full_path) and ($entry ne ".") and ($entry ne "..")) { check_recursively($entry_full_path); } } closedir($folder); } #--- MAIN CODE --- unless(defined @ARGV) { print "\nchmod_selected_folders.pl\njve - oct.2009\n\nusage: ./chmod_selected_folders.pl ... \n\n"; } print "using perm list:\n"; foreach my $pattern (keys %perm_list) { print " * pattern $pattern will be applied permission $perm_list{$pattern}\n"; } # list of folder in stdin, loop on it foreach my $folder_name (@ARGV) { print "processing entries starting at $folder_name\n"; check_recursively($folder_name); } If no pattern matches an entry, the one called **default** will be applied to it.