PerlPowerTools
view release on metacpan or search on metacpan
usage() unless @ARGV > 1;
my $group = shift;
if (length($group) == 0) {
warn "$Program: '' is an invalid group\n";
exit EX_FAILURE;
}
my $gid = getgrnam $group;
unless (defined $gid) {
$gid = $group if $group =~ m/\A[0-9]+\z/;
}
unless (defined $gid) {
warn "$Program: '$group' is an invalid group\n";
exit EX_FAILURE;
}
my %ARGV;
%ARGV = map {$_ => 1} @ARGV if $options {H};
if (exists $options {R}) {
# Recursion.
require File::Find;
File::Find::find (\&modify_file, @ARGV);
}
else {
foreach my $file (@ARGV) {
modify_file($file);
}
}
exit ($warnings ? EX_FAILURE : EX_SUCCESS);
# File::Find is weird. If called with a directory, it will call
# the sub with "." as file name, while having chdir()ed to the
# directory. But it doesn't do that in recursion, just the top
# level ones. And it ain't true that $File::Find::name eq
# "$File::Find::dir/$_" in all cases.
# But it shouldn't matter in this case.
sub modify_file {
my $file = @_ ? shift : $_;
# Now, if this is a symbolic link, it points somewhere,
# *and* we are following symbolic links, we recurse.
# This may never end as symlinks can form loops.
if (-l $file && -e $file &&
($options {L} || $options {H} && $ARGV {$file})) {
# We don't want to recurse symlinks that just happen to
# have the same name as one of the arguments, hence the local.
# Remember that $file is relative to the current directory.
local $ARGV {readlink $file} = 0;
File::Find::find (\&modify_file, readlink $file);
return;
}
my @st = stat $file;
unless (@st) {
warn "$Program: failed to stat '$file': $!\n";
$warnings++;
return;
};
my $uid = $st[4];
unless (chown $uid, $gid, $file) {
warn "$Program: '$file': $!\n";
$warnings++;
}
}
__END__
=pod
=head1 NAME
chgrp - change group ownership of files
=head1 SYNOPSIS
chgrp [-R [-H | -L | -P]] group file [files ...]
=head1 DESCRIPTION
I<chgrp> sets the group ownership of files. The first argument after the
options is the new group.
=head2 OPTIONS
I<chgrp> accepts the options described below. The options I<-L>,
I<-H> and I<-P> are mutually exclusive, and only the last given
option will be honoured. All of I<-L>, I<-H> and I<-P> require the
I<-R> option to be set first.
=over 4
=item -R
Recurse into directories. Any directories are recursively traversed,
and all files and directories will change owner.
=item -L
Follow symbolic links. By default, I<chgrp> will not follow symbolic
links. This is a potential dangerous option, as I<chgrp> will not
check for cycles. Be careful. This option requires the I<-R> option to be set.
=item -H
Follow symbolic links of command line files/directories only. This option
requires the I<-R> option to be set.
=item -P
Do not follow symbolic links at all. This option requires the I<-R> option
to be set.
=back
=head1 ENVIRONMENT
The working of I<chgrp> is not influenced by any environment variables.
=head1 BUGS
( run in 0.478 second using v1.01-cache-2.11-cpan-5511b514fd6 )