Risposte:
Può essere fatto con la seguente linea di shell:
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
è sufficiente impostare il valore corretto per le variabili D1 e D2, puntarle alle directory di origine e di destinazione, eseguire e le directory avranno i permessi sincronizzati.
Ho appena imparato un modo nuovo e semplice per ottenere questo risultato:
getfacl -R /path/to/source > /root/perms.acl
Questo genererà un elenco con tutte le autorizzazioni e le proprietà.
Quindi vai a un livello sopra la destinazione e ripristina le autorizzazioni con
setfacl --restore=/root/perms.acl
Il motivo per cui devi essere di un livello superiore è che tutti i percorsi in perms.acl sono relativi.
Dovrebbe essere fatto come root.
getfacl
e setfacl
non sono necessariamente presenti su tutti i sistemi.
.ac
nel primo comando e .acl
nel secondo?
Se hai l'origine e la destinazione, puoi sincronizzare le tue autorizzazioni con
rsync -ar --perms source/ dest
Non trasferirà i dati, solo le autorizzazioni ...
-r
e --perms
sono ridondanti, ma questo sincronizza ancora se sono l'unica cosa diversa (che è quello che hai detto nella Domanda; se gli alberi non sono effettivamente identici non avresti dovuto dire che lo erano).
Una cosa che potresti fare è usare il comando find per creare uno script con i comandi necessari per copiare le autorizzazioni. Ecco un breve esempio, potresti fare molto di più con le varie opzioni di stampa, tra cui ottenere il proprietario, l'ID del gruppo e così via.
$ 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
...
Due strade:
(in quest'ultimo caso / dst deve esistere)
Modifica: scusa, ho letto male. Non quello che hai chiesto.
Penso che scriverei uno script perl per farlo. Qualcosa di simile a:
#!/usr/bin/perl -nw
my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;
Quindi fai qualcosa del genere:
cd /some/old/orig/path/ ; find . -type d | perlscript
L'ho scritto dalla cima della mia testa e non è stato testato; quindi controllalo prima di lasciarlo correre dilagante. Questo risolve solo le autorizzazioni per le directory esistenti; non modificherà le autorizzazioni per i file, né creerà directory mancanti.
Ho pensato a questo:
find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh
Non è completamente a prova di proiettile, ma fa quello che mi serve.