Использование File :: Path для создания каталога, но владелец и группа установлены неправильно - PullRequest
2 голосов
/ 14 августа 2011

Я пытаюсь написать небольшой скрипт на Perl, который создает структуру каталогов. Для создания каталогов я использую стандартный модуль File :: Path, как показано ниже:

make_path($directory,
    {
        owner   => 'apache',
        group   => 'apache',
        mode    => 0500
    }
);

При выполнении сценария каталог создается как требуется, и umask устанавливается в соответствии с ожиданиями, но как владелец, так и группа файла являются «корневыми». Это неправильно, но где ошибка? Сообщение об ошибке не печатается или не передается параметром error.

Заранее спасибо,

Jost

Ответы [ 3 ]

6 голосов
/ 14 августа 2011

Я только что попробовал и получил тот же результат, что и вы. Я посмотрел на документацию:

perldoc File::Path

... и без упоминания опции «владелец». Тем не менее, поиск последней версии документации (2.08, AFAICT), и это там. Можете ли вы проверить версию модуля в вашей системе?

perl -MFile::Path -e 'print $File::Path::VERSION'

Если вы не используете 2.08, это может быть проблемой. Я пытаюсь отследить журнал изменений для модуля прямо сейчас, но с трудом ...

[Позже]

ОК, вот что вы хотите сделать:

#!/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;

В конечном счете, последняя строка - это та, которую вы хотите принять к сведению. Вы не можете установить владельца, когда создаете его с этой версией File :: Path, но вы можете изменить его. 33 в моем примере - это UID пользователя www-data в моей системе; очевидно, вы хотите изменить 33 на что-то более разумное для вашей системы. Кроме того, вам необходимо убедиться, что ваш скрипт запускается с привилегиями, которые способны сделать это. Например, если вы запустите его как пользователь с низким уровнем прав, он не будет работать, но если вы запустите его как пользователь root, будет работать chown. Возможно, вы захотите найти там золотую середину.

2 голосов
/ 14 августа 2011

Я бы сказал, что это ошибка в File::Path; он тихо игнорирует ключи, которые не распознает.

#!/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";

(Обратите внимание, что это предполагает, что у вас есть учетная запись в вашей системе с именем "kst"; отрегулируйте по мере необходимости для вашей системы.)

Когда я запускаю это в sudo, используя File :: Path версии 2.07_03 с Perl 5.010001, созданный каталог принадлежит root; когда я делаю то же самое, но используя File :: Path версии 2.08_01 с Perl 5.014000, каталог принадлежит kst. В любом случае нет никаких признаков проблемы с нераспознанными ключами (owner и nosuchkey для более старой версии, просто nosuchkey для более новой версии).

perldoc File::Path не решает эту проблему (если я ее не пропустил), и я не вижу какого-либо простого способа определить, может ли используемый File::Path обрабатывать более новые параметры. (Вы можете проверить $File::Path:VERSION, но для этого нужно знать, когда была реализована новая опция.)

Я только что сообщил об этом .

0 голосов
/ 13 августа 2013

Ответ Кенни полезен только тогда, когда вы хотите создать один каталог, а не больше вложенных каталогов - например.make_path ( 'foo/bar' ); Во втором случае будет изменен только владелец / группа последнего каталога.

Более правильный путь может быть примерно таким:

#!/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 );
}
...