NOTE: The OS usually won't let you change ownership of a file or directory unless you are the superuser (i.e. root).
Now, we got that out of the way...
The File::Find
module does what you want. Use use warnings;
instead of -w
:
use strict;
use warnings;
use feature qw(say);
use autodie;
use File::Find;
finddepth sub {
return unless -d; # You want only directories...
chown deep, deep, $File::Find::name
or warn qq(Couldn't change ownership of "$File::Find::name\n");
}, ".";
The File::Find
package imports a find
and a finddepth
subroutine into your Perl program.
Both work pretty much the same. They both recurse deeply into your directory and both take as their first argument a subroutine that's used to operate on the found files, and list of directories to operate on.
The name of the file is placed in $_
and you are placed in the directory of that file. That makes it easy to run the standard tests on the file. Here, I'm rejecting anything that's not a directory. It's one of the few places where I'll use $_
as the default.
The full name of the file (from the directory you're searching is placed in $File::Find::name
and the name of that file's directory is $File::Find::dir
.
I prefer to put my subroutine embedded in my find
, but you can also put a reference to another subroutine in there too. Both of these are more or less equivalent:
my @directories;
find sub {
return unless -d;
push @directories, $File::Find::name;
}, ".";
my @directories;
find \&wanted, ".";
sub wanted {
return unless -d;
push @directories, $File::Find::name;
}
In both of these, I'm gathering the names of all of the directories in my path and putting them in @directories
. I like the first one because it keeps my wanted subroutine and my find
together. Plus, the mysteriously undeclared @directories
in my subroutine doesn't look so mysterious and undeclared. I declared my @directories;
right above the find
.
By the way, this is how I usually use find
. I find what I want, and place them into an array. Otherwise, you're stuck putting all of your code into your wanted subroutine.