Odpowiedzi:
Można to zrobić za pomocą następującej linii powłoki:
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
po prostu ustaw odpowiednią wartość dla zmiennych D1 i D2, wskaż je na katalogach źródłowym i docelowym, uruchom, a katalogi będą miały zsynchronizowane uprawnienia.
Właśnie nauczyłem się nowego i prostego sposobu na osiągnięcie tego:
getfacl -R /path/to/source > /root/perms.acl
Spowoduje to wygenerowanie listy ze wszystkimi uprawnieniami i prawami własności.
Następnie przejdź do jednego poziomu powyżej miejsca docelowego i przywróć uprawnienia za pomocą
setfacl --restore=/root/perms.acl
Powodem, dla którego musisz znajdować się o jeden poziom wyżej, jest to, że wszystkie ścieżki w pliku perms.acl są względne.
Powinny być wykonane jako root.
getfacl
i setfacl
niekoniecznie są one obecne we wszystkich systemach.
.ac
w pierwszym poleceniu i .acl
w drugim?
Jeśli masz źródło i miejsce docelowe, możesz zsynchronizować swoje uprawnienia z
rsync -ar --perms source/ dest
Nie przeniesie danych, tylko uprawnienia ...
-r
i --perms
są zbędne, ale nadal synchronizują perms, jeśli są jedyną rzeczą, która jest inna (co powiedziałeś w pytaniu; jeśli drzewa nie są w rzeczywistości identyczne, nie powinieneś był powiedzieć, że były).
Jedną rzeczą, którą możesz zrobić, to użyć polecenia find do zbudowania skryptu z poleceniami potrzebnymi do skopiowania uprawnień. Oto szybki przykład, możesz zrobić o wiele więcej z różnymi opcjami printf, w tym uzyskać właściciela, identyfikator grupy i tak dalej.
$ 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
...
Dwie drogi:
(w tym ostatnim przypadku musi istnieć / dst)
Edycja: przepraszam, źle odczytałem. Nie to o co prosiłeś.
Myślę, że napisałbym do tego skrypt perla. Coś jak:
#!/usr/bin/perl -nw
my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;
Następnie zrób coś takiego:
cd /some/old/orig/path/ ; find . -type d | perlscript
Zapisałem to sobie z głowy i nie zostało to przetestowane; więc sprawdź to, zanim zacznie szaleć. To naprawia tylko uprawnienia do istniejących katalogów; nie zmieni uprawnień do plików ani nie utworzy brakujących katalogów.
Wymyśliłem to:
find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh
Nie jest w pełni kuloodporny, ale robi to, czego potrzebuję.