Mengkloning kepemilikan dan izin dari file lain?

125

Apakah ada perintah atau panji untuk mengkloning kepemilikan dan izin pengguna / grup pada file dari file lain? Untuk membuat perms dan kepemilikan persis dengan file lain?

pengguna394
sumber

Jawaban:

175

Di GNU / Linux chowndan chmodpunya --referenceopsi

chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
enzotib
sumber
1
Bisakah Anda merujuk ke jawaban ini (dan mungkin mengutipnya) sebagai jawaban untuk pertanyaan saya: unix.stackexchange.com/questions/44253/… ? , Saya pikir saya akan menjadi tambahan yang bagus dan saya ingin menemukan suara di sana untuk itu.
Grzegorz Wierzowiecki
@ GrzegorzWierzowiecki: mungkin pertanyaan itu harus ditutup, tetapi sedikit berbeda dari ini dan sudah memiliki jawaban, jadi saya lebih baik tidak melakukan apa pun.
enzotib
Seperti yang Anda inginkan dan sarankan. Terima kasih atas bantuannya, saya tidak pernah memperhatikan --referenceparameter chmoddan chownsebelumnya :).
Grzegorz Wierzowiecki
12

Pada setiap unix dengan utilitas GNU, seperti Linux (tidak tertanam) atau Cygwin, Anda dapat menggunakan chmod --referencedanchown --reference .

Jika sistem Anda memiliki ACL , coba perintah ACL getfacldan setfacl. Perintah-perintah ini sedikit berbeda dari sistem ke sistem, tetapi pada banyak Anda dapat menggunakan getfacl other_file | setfacl -bnM - file_to_changeuntuk menyalin izin. Ini tidak menyalin kepemilikan; Anda dapat melakukannya dengan penguraian yang hati-hati ls -l other_file, dengan asumsi bahwa Anda tidak memiliki nama pengguna atau grup yang berisi spasi putih.

LC_ALL=C ls -l other_file | {
  read -r permissions links user group stuff;
  chown -- "$user:$group" file_to_change
}
getfacl other_file | setfacl -bnM - file_to_change
Gilles
sumber
1
Anda harus menginstal ACL dan sistem file terpasang dengan ACL diaktifkan.
enzotib
2
@enzotib Setidaknya di Linux, alat ACL akan berfungsi untuk menyalin izin (tetapi bukan kepemilikan) meskipun sumber dan sistem file target tidak mendukung ACL.
Gilles
7

Melakukan perintah bash berdasarkan respons Matteo :)

Kode:

chmod $( stat -f '%p' "$1" ) "${@:2}"

Pemakaian:

cp-permissions <from> <to>...

gunung berapi
sumber
5
Egad! Di mana Anda belajar mengatakannya ${*:2}? Jangan pernah melakukan itu lagi! Itu akan gagal jika salah satu nama file mengandung spasi (atau tab). Gunakan "${@:2}". Juga, gunakan "$1"bukan hanya $1.
G-Man
chmod "$(stat -c '%a' "$fromfile")" tofiledalam GNU Coreutils, tetapi Anda mungkin juga menggunakan --referencedalam kasus itu karena statutilitas CLI bukan POSIX, bahkan mengatakan pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.htmlyang ls -l tidak akan memotongnya: "Output dari ls (dengan -l dan opsi terkait) berisi informasi yang secara logis dapat digunakan oleh utilitas seperti chmod dan sentuh untuk mengembalikan file ke kondisi yang diketahui. Namun, informasi ini disajikan dalam format yang tidak dapat digunakan langsung oleh utilitas tersebut atau menjadi mudah diterjemahkan ke dalam format yang bisa digunakan. "
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
5

Jika Anda tidak menggunakan sistem dengan chmod / chown GNU (yang mendukung --referenceopsi), Anda dapat mencoba mengurai output darils -l

Berikut skrip kecil untuk chmod(jika Anda memiliki tampilan yang mendukung regex yang diperluas, skrip tersebut dapat ditulis dengan cara yang lebih mudah dibaca ...)

#!/bin/sh

reference=$1
shift
files=$*

# strip the permissions (whith extended regexes could be more readable)
OWNER=$(ls -l ${reference} | sed -e "s/.\(...\).*/\1/"       | sed -e "s/[-]//g" )
GROUP=$(ls -l ${reference} | sed -e "s/....\(...\).*/\1/"    | sed -e "s/[-]//g" )
OTHER=$(ls -l ${reference} | sed -e "s/.......\(...\).*/\1/" | sed -e "s/[-]//g" )

chmod u=${OWNER},g=${GROUP},o=${OTHER} ${files}

PEMBARUAN :

Ini bahkan lebih mudah menggunakan stat:

chmod $( stat -f '%p' ${reference} ) ${files}
Matteo
sumber
2
Alih-alih ls -lmem -parsing output, Anda bisa mem-parsing statoutput.
jfg956
@ jfgagne: terima kasih masuk akal saya tidak tahu mengapa saya tidak memikirkannya sejak awal. Saya memperbarui jawabannya
Matteo
1
Anda menggunakan statsintaks * BSD di sini. chmod $(stat ...)Perintah Anda tidak akan berfungsi karena %psendirian menghasilkan terlalu banyak informasi untuk * BSD chmod, gunakan %Lphanya untuk output bit u / g / o. Sesuatu yang sedikit lebih rumit akan diperlukan untuk bit sticky / setuid / setgid.
mr.spuratic
0

Saya ingin menambahkan penyesuaian pada skrip Matteo . A for loop harus digunakan untuk memvalidasi bahwa file ada sebelum benar-benar menjalankan perintah chmod pada mereka. Ini akan membuat kesalahan skrip lebih anggun.

Saya pikir ini adalah pilihan terbaik karena dapat digunakan untuk semua * nix OS, seperti Solaris, Linux, dll.

#!/bin/sh

reference=$1
shift
files=$*

for file in $reference $files; do
  [ -f $file ] || { echo "$file does not exist"; exit 1; }
done

# strip the permissions (whith extended regexes could be more readable)
OWNER=$(ls -l ${reference} | sed -e "s/.\(...\).*/\1/" | sed -e "s/[-]//g" )
GROUP=$(ls -l ${reference} | sed -e "s/....\(...\).*/\1/" | sed -e "s/[-]//g" )
OTHER=$(ls -l ${reference} | sed -e "s/.......\(...\).*/\1/" | sed -e "s/[-]//g" )

chmod u=${OWNER},g=${GROUP},o=${OTHER} ${files}

Saya menemukan bahwa di salah satu mesin Solaris 10 saya, stattidak ditemukan. Itu mungkin masalah dengan konfigurasi saya.

David
sumber
0

Ini bekerja untuk saya:

cp -p --attributes-only <from> <to>

pengguna172554
sumber