Jawaban:
Ini dapat dilakukan dengan garis shell berikut:
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
cukup atur nilai yang tepat untuk variabel D1 dan D2, arahkan mereka ke direktori sumber dan tujuan, jalankan dan dirs akan memiliki izin dalam sinkronisasi.
Saya baru belajar cara baru dan sederhana untuk mencapai ini:
getfacl -R /path/to/source > /root/perms.acl
Ini akan menghasilkan daftar dengan semua izin dan kepemilikan.
Lalu pergi ke satu tingkat di atas tujuan dan kembalikan izin dengan
setfacl --restore=/root/perms.acl
Alasan Anda harus satu tingkat di atas adalah bahwa semua jalur di perms.acl relatif.
Harus dilakukan sebagai root.
getfacl
dan setfacl
tidak selalu ada pada semua sistem.
.ac
perintah pertama dan .acl
kedua?
Jika Anda memiliki sumber dan tujuan, Anda dapat menyinkronkan izin Anda dengan
rsync -ar --perms source/ dest
Itu tidak akan mentransfer data, hanya izin ...
-r
dan --perms
berlebihan, tetapi ini masih mensinkronkan perm jika mereka satu-satunya hal yang berbeda (yang Anda katakan dalam Pertanyaan; jika pohon tidak benar-benar identik, Anda seharusnya tidak mengatakan bahwa itu adalah).
Satu hal yang bisa Anda lakukan adalah menggunakan perintah find untuk membangun skrip dengan perintah yang Anda butuhkan untuk menyalin izin. Ini adalah contoh cepat, Anda dapat melakukan lebih banyak hal dengan berbagai opsi printf, termasuk mendapatkan pemilik, id grup, dan sebagainya.
$ 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
...
Dua arah:
(dalam kasus terakhir / dst harus ada)
Sunting: maaf, saya salah membaca. Bukan apa yang kamu minta.
Saya pikir saya akan menulis skrip perl untuk melakukannya. Sesuatu seperti:
#!/usr/bin/perl -nw
my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;
Kemudian lakukan sesuatu seperti ini:
cd /some/old/orig/path/ ; find . -type d | perlscript
Saya menulis ini dari atas kepala saya, dan belum diuji; jadi periksalah sebelum kamu membiarkannya merajalela. Ini hanya memperbaiki izin pada direktori yang ada; itu tidak akan mengubah izin pada file, juga tidak akan membuat direktori yang hilang.
Saya datang dengan ini:
find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh
Ini bukan bukti peluru sepenuhnya, tetapi melakukan apa yang saya butuhkan.