Відповіді:
Це можна зробити за допомогою наступної лінії оболонки:
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, вкажіть їх на каталоги джерела та призначення, запустіть, і dirs матимуть дозволи на синхронізацію.
Щойно я навчився нового і простого способу досягти цього:
getfacl -R /path/to/source > /root/perms.acl
Це створить список із усіма дозволами та правами власності.
Потім перейдіть на один рівень над пунктом призначення та відновіть дозволи
setfacl --restore=/root/perms.acl
Причина, по якій ви повинні бути на один рівень вище, полягає в тому, що всі шляхи в perms.acl відносні.
Слід робити як корінь.
getfacl
і setfacl
не обов'язково присутній у всіх системах.
.ac
в першій команді і .acl
в другій?
Якщо у вас є джерело та призначення, ви можете синхронізувати свої дозволи з
rsync -ar --perms source/ dest
Він не передасть дані, лише дозволи ...
-r
і --perms
є надлишковими, але це все ще синхронізує хімічні речовини, якщо вони є єдиним, що відрізняється (про що ви сказали в запитанні; якщо дерева насправді не однакові, ви не повинні сказати, що вони були).
Одне, що можна зробити, - це скористатися командою 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
...
Два способи:
(в останньому випадку / dst повинен існувати)
Редагувати: вибачте, я неправильно прочитав. Не те, що ви просили.
Я думаю, що я написав би сценарій 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
Я це записав у верхній частині голови, і це не перевірено; тому перевірте це, перш ніж пускати його на розгул. Це фіксує лише дозволи на наявні каталоги; він не змінює дозволи на файли, а також не створюватиме відсутніх каталогів.
Я придумав це:
find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh
Це не повністю захищене від кулі, але робить те, що мені потрібно.