Копировать разрешения в идентичное дерево на Linux / Unix


22

у меня есть дерево файлов с правильным разрешением. тогда у меня есть (файловое) идентичное дерево (с другим жестким содержанием файла) с неправильными разрешениями.

Как я могу перенести макет разрешений из одного дерева в другое?

Ответы:


8

Это можно сделать с помощью следующей строки оболочки:

D1=foo; D2=foo2; for entry in $(find $D1  -exec stat -f "%N:%Mp%Lp" {} \;); do $(echo $entry | sed 's#'$D1'#'$D2'#' | awk -F: '{printf ("chmod %s %s\n", $2, $1)}') ; done

просто установите правильное значение для переменных D1 и D2, укажите их на каталоги источника и назначения, запустите, и у каталогов будут права доступа в синхронизации.


1
Это предполагает, что стат присутствует. К сожалению, я обнаружил, что команда stat часто отсутствует.
Мэй

@ Дэвид, я не знаю, чтобы в такой системе не было статистики. Но довольно просто использовать следующую версию "восьмеричной ls" и соответствующим образом приспособить данное решение: alias ols = "ls -la | awk '{k = 0; для (i = 0; i <= 8; i ++) k + = ((substr (\ $ 1, i + 2,1) ~ / [rwx] /) * 2 ^ (8-i)); if (k) printf (\ "% 0o \", k); print} ' "
drAlberT

Разрывается, когда любой путь содержит какой- либо специальный символ (пробел, начинается с тире и т. Д.).
n.st

31

Я только что узнал новый и простой способ сделать это:

getfacl -R /path/to/source > /root/perms.acl

Это создаст список со всеми разрешениями и владельцами.

Затем перейдите на один уровень выше места назначения и восстановите права доступа с помощью

setfacl --restore=/root/perms.acl

Причина, по которой вы должны быть на один уровень выше, заключается в том, что все пути в perms.acl являются относительными.

Должно быть сделано как root.


Это очень простой и простой способ резервного копирования и восстановления разрешений. Однако обратите внимание, что getfaclи setfaclне обязательно присутствуют во всех системах.
the-wabbit

Правильно ли иметь .acв первой команде и .aclво второй?
сфарбота

1
@sfarbota: Нет, это была опечатка! Исправлено сейчас. Спасибо за указание на это.
marlar

13

Если у вас есть source и dest, вы можете синхронизировать ваши разрешения с rsync -ar --perms source/ dest

Он не будет передавать данные, только разрешения ...


1
Нет, он будет копировать файлы, если метки времени отличаются
yawniek

@yawniek -rи --permsявляются избыточными, но это все еще синхронизации завивки , если они единственное , что отличается (это то , что вы сказали в вопросе, если деревья не фактически идентичны , вы не должны были сказать , что они были).
Крис С

Хорошо, тогда мне было неясно, я имел в виду, что древовидная структура одинакова.
yawniek

12

Одна вещь, которую вы можете сделать, это использовать команду find для создания скрипта с командами, которые вам необходимы для копирования разрешений. Вот быстрый пример, вы могли бы сделать гораздо больше с различными параметрами printf, включая получение владельца, идентификатора группы и так далее.

$ find /var/log -type d -printf "chmod %m %p \n" > reset_perms
$ cat reset_perms
chmod 755 /var/log
chmod 755 /var/log/apt
chmod 750 /var/log/apache2
chmod 755 /var/log/fsck
chmod 755 /var/log/gdm
chmod 755 /var/log/cups
chmod 2750 /var/log/exim4
...

1
Я подозреваю, что аргумент -printf для поиска является расширением GNU? У HP-UX find его нет.
Мэй

1
Даже не найдя опцию printf, можно использовать опцию ls (или, в худшем случае, pipe к xargs ls -l) и сохранить в файл. Минуту или две поиска и замены, и одна будет иметь скрипт с chmod для каждого файла.
mpez0

0

Два пути:

  1. Если это работает на вашем бренде UNIX: cp -ax / src / dest
  2. Или, если нет, это переносная версия: (cd / src && tar cpf -.) | (cd / dst && tar xpf -)

(в последнем случае / dst должен существовать)

Изменить: извините, я неправильно прочитал. Не то, что вы спросили.


Стоит отметить, что -a (для архива) является дополнением GNU к cp, я никогда не видел его ни в одной другой системе. Это просто сокращение от -dpR (без разыменования, рекурсия, сохранение разрешений). Параметры R и p должны быть в любой версии cp
theotherreceive

0

Я думаю, я бы написал Perl-скрипт для этого. Что-то типа:

#!/usr/bin/perl -nw

my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;

Затем сделайте что-то вроде этого:

cd /some/old/orig/path/ ; find . -type d | perlscript

Я написал это на макушке моей головы, и это не было проверено; так что проверяйте это, прежде чем позволить ему стать безудержным. Это только исправляет разрешения на существующие каталоги; он не изменит разрешения для файлов и не создаст отсутствующие каталоги.


0

Я придумал это:

find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh

Это не полностью пуленепробиваемое, но делает то, что мне нужно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.