使用 File::Path 创建目录,但所有者和组设置不正确

发布于 2024-11-29 08:18:58 字数 333 浏览 0 评论 0原文

我正在尝试编写一个小的 Perl 脚本来创建目录结构。为了创建目录,我使用标准模块 File::Path,如下所示:

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

执行脚本时,将根据需要创建目录并按预期设置 umask,但文件的所有者和组都是“root”。这是错误的,但是错误在哪里呢?错误参数不会打印或给出任何错误消息。

预先感谢,

乔斯特

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',
        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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

私野 2024-12-06 08:18:58

我刚刚尝试了一下,得到了和你一样的结果。我查看了文档:

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 是​​我系统上 www-data 用户的 UID;显然,您希望将 33 更改为对您的系统更合理的值。此外,您还需要确保您的脚本以能够执行此操作的权限运行。例如,如果您以低级用户身份运行它,它将不起作用,但如果您以 root 身份运行它,则 chown 将起作用。您可能想在那里找到一些中间立场。

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.

死开点丶别碍眼 2024-12-06 08:18:58

我认为这是 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”的帐户;根据您的系统需要进行调整。)

当我使用 File::Path 版本 2.07_03 和 Perl 5.010001 在 sudo 下运行此命令时,创建的目录由root拥有;当我做完全相同的事情,但使用 File::Path 版本 2.08_01 和 Perl 5.014000 时,该目录由 kst 所有。无论哪种情况,都没有迹象表明无法识别的密钥存在问题(旧版本的 ownernosuchkey,新版本的只是 nosuchkey )。

perldoc File::Path 没有解决这个问题(除非我错过了),并且我没有看到程序有任何干净的方法来确定 File::Path code> 它使用的可以处理较新的选项。 (您可以检查 $File::Path:VERSION,但这需要知道何时实施新选项。)

我刚刚 报告了此问题

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.

分開簡單 2024-12-06 08:18:58

仅当您想创建单个目录而不是更多嵌套目录时,肯尼的回答才有用 - 例如。 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 );
}

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 );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文