perl 保留模式和所有权的递归目录复制,没有内容
Recursive directory copy in perl preserving mode and ownership, without content
我想使用 perl 在本地复制没有内容的目录结构,但保留所有者和模式。我发现 File::Copy::Recursive 提供 dircopy
除了保留所有权之外的所有功能。有没有一种方法可以在不明确遍历新旧目录并比较所有者的情况下实现这一目标?当然,这需要在实现的某个地方发生,但我想知道它是否已经在某个地方实现,这样我就不必重新发明它。
编辑:事实证明 dircopy
也会复制文件,所以这不是我想要的。
如果不需要便携性,我会使用系统提供的工具。它们会更快、更可靠。 tar
可以重新创建权限和所有权。
如果你想复制其中的目录和文件,很简单:
( cd "$SRC" ; tar c ) | ( cd "$DST" ; tar x --preserve --same-owner )
但是您要求重新创建没有内容的目录结构。为此,您可以使用以下内容:
( cd "$SRC" ; find -type d -exec \
sh -c 'tar c --no-recursion "$@" | ( cd "$DST" ; tar x --preserve --same-owner )' \
dummy {} + )
$SRC
和 $DST
分别是基本源目录和目标目录。
当然,这些命令需要作为 root
执行以保留所有权。
最后我自己做了:
sub dirCopy {
my $old = shift;
my $new = shift;
if( -d $new ){return(1)}
my $old_base = dirname($old);
my $new_base = dirname($new);
unless( -d $new_base ){dirCopy($old_base, $new_base)}
my @old_stat = stat($old) or die("Could not stat $old");
my $old_mode = $old_stat[2];
my $old_uid = $old_stat[4];
my $old_gid = $old_stat[5];
mkdir($new) or die("Could not mkdir $new");
chown($old_uid, $old_gid, ($new)) or die("Could not chown $new");
chmod($old_mode, ($new)) or die("Could not chmod $new");
return(1);
}
我想使用 perl 在本地复制没有内容的目录结构,但保留所有者和模式。我发现 File::Copy::Recursive 提供 dircopy
除了保留所有权之外的所有功能。有没有一种方法可以在不明确遍历新旧目录并比较所有者的情况下实现这一目标?当然,这需要在实现的某个地方发生,但我想知道它是否已经在某个地方实现,这样我就不必重新发明它。
编辑:事实证明 dircopy
也会复制文件,所以这不是我想要的。
如果不需要便携性,我会使用系统提供的工具。它们会更快、更可靠。 tar
可以重新创建权限和所有权。
如果你想复制其中的目录和文件,很简单:
( cd "$SRC" ; tar c ) | ( cd "$DST" ; tar x --preserve --same-owner )
但是您要求重新创建没有内容的目录结构。为此,您可以使用以下内容:
( cd "$SRC" ; find -type d -exec \
sh -c 'tar c --no-recursion "$@" | ( cd "$DST" ; tar x --preserve --same-owner )' \
dummy {} + )
$SRC
和 $DST
分别是基本源目录和目标目录。
当然,这些命令需要作为 root
执行以保留所有权。
最后我自己做了:
sub dirCopy {
my $old = shift;
my $new = shift;
if( -d $new ){return(1)}
my $old_base = dirname($old);
my $new_base = dirname($new);
unless( -d $new_base ){dirCopy($old_base, $new_base)}
my @old_stat = stat($old) or die("Could not stat $old");
my $old_mode = $old_stat[2];
my $old_uid = $old_stat[4];
my $old_gid = $old_stat[5];
mkdir($new) or die("Could not mkdir $new");
chown($old_uid, $old_gid, ($new)) or die("Could not chown $new");
chmod($old_mode, ($new)) or die("Could not chmod $new");
return(1);
}