Using File::Path to create directory, but owner and group are not set correctly
I'm trying to write a small Perl script which creates a directory structure. To create the directories, I use the standard module File::Path, as follows:
make_path($directory,
{
owner => 'apache',
group => 'apache',
开发者_如何学Python mode => 0500
}
);
When executing the script, the directory is created as wanted and the umask is set as expected, but both owner and group of the file are "root". This is wrong, but where is the error? No error message is printed or given by the error-parameter.
Thanks in advance,
Jost
I just tried it and got the same outcome as you. I looked at the documentation:
perldoc File::Path
...and no mention of 'owner' option. However, searching the latest version (2.08, AFAICT) documentation, and it's there. Can you check the version of the module on your system?
perl -MFile::Path -e 'print $File::Path::VERSION'
If you're not running 2.08, that might be the problem. I'm attempting to track down the changelog for the module right now, but having difficulty...
[ Later ]
OK, so here's what you want to do:
#!/usr/bin/perl -w
use strict;
use File::Path qw( make_path );
my $directory = $ARGV[0];
my $owner = 33;
make_path( $directory, { mode => 0500 } );
chown 33, 33, $directory;
Ultimately, the last line is the one you want to take note of. You can't set the owner when you create it with that version of File::Path, but you can change it. The 33 in my example is the UID of the www-data user on my system; clearly, you want to change 33 to something more sensible for your system. Also, you will need to make sure that your script runs with privileges that are capable of doing this. For example, if you run this as a lowly user, it won't work, but if you run it as root, the chown will work. You might want to find some middle ground there.
I would argue that this is a bug in File::Path
; it quietly ignores keys that it doesn't recognize.
#!/usr/bin/perl
use strict;
use warnings;
use File::Path;
print "Using File::Path version $File::Path::VERSION with Perl $]\n";
my $tmpdir = "/tmp/file-path-test-$$";
print "Creating $tmpdir\n";
mkdir $tmpdir, 0777 or die "$tmpdir: $!\n";
my @result = File::Path::make_path
( "$tmpdir/new-dir",
{ owner => 'kst',
mode => 0500,
nosuchkey => 'WTF?' } );
print "Created ( @result )\n";
(Note that this assumes you have an account on your system named "kst"; adjust as needed for your system.)
When I run this under sudo
using File::Path version 2.07_03 with Perl 5.010001, the created directory is owned by root
; when I do exactly the same thing, but using File::Path version 2.08_01 with Perl 5.014000, the directory is owned by kst
. In either case, there's no indication of a problem with the unrecognized keys (owner
and nosuchkey
for the older version, just nosuchkey
for the newer version).
perldoc File::Path
doesn't address this issue (unless I missed it), and I don't see any clean way for a program to determine whether the File::Path
it's using can handle the newer options. (You could check $File::Path:VERSION
, but that requires knowing when a new option was implemented.)
I've just reported this.
Answer by Kenny is useful only when you want to create single directory, not more nested directories - eg. make_path ( 'foo/bar' );
In second case only owner/group of last directory will be changed.
More correct way can be something like this:
#!/usr/bin/perl -w
use strict;
use File::Path qw( make_path );
use File::Spec;
my $directory = $ARGV[0];
my $gid = getgrnam( "my_group" );
my $uid = getpwnam( "my_user" );
make_path( $directory, { mode => 0750 } );
my @directories = File::Spec->splitdir( $directory );
my @path;
foreach my $dir ( @directories ) {
push( @path, $dir );
chown $uid, $gid, File::Spec->catdir( @path );
}
精彩评论