Скопіюйте дозволи на однакове дерево на 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, вкажіть їх на каталоги джерела та призначення, запустіть, і dirs матимуть дозволи на синхронізацію.


1
Це передбачає, що stat присутній. На жаль, я виявив, що в командній статистиці часто немає.
Май

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

Перерви, коли будь-який задіяний шлях містить будь- який спеціальний символ (пробіл, починається з тире та ін.).
n.st

31

Щойно я навчився нового і простого способу досягти цього:

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

Це створить список із усіма дозволами та правами власності.

Потім перейдіть на один рівень над пунктом призначення та відновіть дозволи

setfacl --restore=/root/perms.acl

Причина, по якій ви повинні бути на один рівень вище, полягає в тому, що всі шляхи в perms.acl відносні.

Слід робити як корінь.


це дуже простий і простий спосіб резервного копіювання та відновлення дозволів. Однак слід зазначити , що getfaclі setfaclне обов'язково присутній у всіх системах.
the wabbit

Чи правильно мати .acв першій команді і .aclв другій?
sfarbota

1
@sfarbota: Ні, це був помилковий помилок! Виправлено зараз. Дякуємо, що вказали на це.
березня 1717 року

13

Якщо у вас є джерело та призначення, ви можете синхронізувати свої дозволи з 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 знайти його не має.
Май

1
Навіть не маючи опції printf для пошуку, можна скористатися параметром ls (або, в гіршому випадку, передати на 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.