โคลนความเป็นเจ้าของและการอนุญาตจากไฟล์อื่นหรือไม่


125

มีคำสั่งหรือการตั้งค่าสถานะเพื่อโคลนความเป็นเจ้าของผู้ใช้ / กลุ่มและการอนุญาตในไฟล์จากไฟล์อื่นหรือไม่? ที่จะทำให้ perms และความเป็นเจ้าของที่แน่นอนของไฟล์อื่นได้หรือไม่

คำตอบ:


175

บน GNU / Linux chownและchmodมี--referenceตัวเลือก

chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile

1
คุณสามารถอ้างอิงถึงคำตอบนี้ (และน่าจะอ้างถึง) เป็นคำตอบสำหรับคำถามของฉัน: unix.stackexchange.com/questions/44253/ …? ฉันคิดว่าฉันจะเป็นส่วนเสริมที่ดีและฉันชอบที่จะหาคะแนนที่นั่น
Grzegorz Wierzowiecki

@GrzegorzWierzowiecki: อาจเป็นคำถามที่ควรจะปิด แต่แตกต่างกันเล็กน้อยกว่านี้และมีคำตอบอยู่แล้วดังนั้นฉันไม่ทำอะไรเลยดีกว่า
enzotib

ตามที่คุณต้องการและแนะนำ ขอบคุณสำหรับความช่วยเหลือฉันไม่เคยใส่ใจ--referenceพารามิเตอร์ของchmodและchownก่อน :)
Grzegorz Wierzowiecki

12

บน Unix ใด ๆ กับสาธารณูปโภค GNU เช่น (ไม่ใช่ฝังตัว) Linux หรือ Cygwin คุณสามารถใช้และchmod --referencechown --reference

หากระบบของคุณมีACLsลองคำสั่งของ ACL และgetfacl setfaclคำสั่งเหล่านี้แตกต่างกันเล็กน้อยจากระบบไปยังระบบ แต่ในหลาย ๆ คุณสามารถใช้getfacl other_file | setfacl -bnM - file_to_changeเพื่อคัดลอกสิทธิ์ สิ่งนี้ไม่ได้คัดลอกความเป็นเจ้าของ คุณสามารถทำได้ด้วยการแยกวิเคราะห์อย่างระมัดระวังls -l other_fileโดยสมมติว่าคุณไม่มีชื่อผู้ใช้หรือกลุ่มที่มีช่องว่าง

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

1
คุณควรมีการติดตั้ง ACL และระบบไฟล์ติดตั้งด้วยการเปิดใช้งาน ACL
enzotib

2
@enzotib อย่างน้อยที่สุดบน Linux เครื่องมือ ACL จะทำงานเพื่อคัดลอกการอนุญาต (แต่ไม่ใช่การเป็นเจ้าของ) แม้ว่าระบบไฟล์ต้นทางและปลายทางจะไม่รองรับ ACL
Gilles

7

ทำคำสั่ง bashตามการตอบสนองของMatteo :)

รหัส:

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

การใช้งาน:

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


5
Egad! คุณเรียนรู้ที่จะพูด${*:2}ที่ไหน ไม่เคยทำเช่นนั้นอีกครั้ง! ซึ่งจะล้มเหลวหากชื่อไฟล์ใดมีช่องว่าง (หรือแท็บ) "${@:2}"ใช้ นอกจากนี้ยังใช้แทนเพียง"$1" $1
G-Man

chmod "$(stat -c '%a' "$fromfile")" tofileใน GNU Coreutils แต่คุณอาจใช้--referenceในกรณีนี้เนื่องจากstatยูทิลิตี้ CLI ไม่ใช่ POSIX มันยังบอกว่าpubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html นั่น ls -lจะไม่ตัด: "ผลลัพธ์ของ ls (พร้อมกับ -l และตัวเลือกที่เกี่ยวข้อง) มีข้อมูลที่สามารถใช้ประโยชน์ได้โดยยูทิลิตี้เช่น chmod และ touch เพื่อกู้คืนไฟล์กลับสู่สถานะที่รู้จักอย่างไรก็ตามข้อมูลนี้นำเสนอในรูปแบบที่ไม่สามารถใช้โดยตรงจากยูทิลิตี้เหล่านั้นหรือ แปลเป็นรูปแบบที่สามารถใช้ได้ง่าย "
Ciro Santilli 事件改造中心法轮功六四事件

5

หากคุณไม่ได้ใช้ระบบที่มี chmod / chown ของ GNU (ซึ่งรองรับ--referenceตัวเลือก) คุณสามารถลองแยกวิเคราะห์ผลลัพธ์ของls -l

นี่เป็นสคริปต์เล็ก ๆ สำหรับchmod(ถ้าคุณเห็นว่าสนับสนุน regexes เพิ่มเติมพวกเขาสามารถเขียนในวิธีที่อ่านได้มากขึ้น ... )

#!/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}

อัปเดต :

สิ่งนี้ง่ายยิ่งขึ้นเมื่อใช้stat:

chmod $( stat -f '%p' ${reference} ) ${files}

2
แทนที่จะแยกวิเคราะห์ls -lเอาต์พุตคุณสามารถแยกวิเคราะห์statเอาต์พุตได้
jfg956

@jfgagne: ขอบคุณทำให้รู้สึกฉันไม่รู้ว่าทำไมฉันไม่คิดเกี่ยวกับมันในตอนแรก ฉันอัปเดตคำตอบ
มัตเตโอ

1
คุณกำลังใช้statไวยากรณ์* BSD ที่นี่ chmod $(stat ...)คำสั่งของคุณจะไม่ทำงานเพราะ%pเพียงอย่างเดียวส่งออกข้อมูลมากเกินไปสำหรับ * BSD's chmodใช้%Lpเพื่อส่งออกเพียงบิต u / g / o จะต้องมีบางสิ่งที่ซับซ้อนกว่านี้เล็กน้อยสำหรับบิตเหนียว / setuid / setgid
mr.spuratic

0

ฉันต้องการเพิ่มการปรับแก้สคริปต์ของMatteo ควรใช้สำหรับ for เพื่อตรวจสอบความถูกต้องของไฟล์ก่อนที่จะรันคำสั่ง chmod สิ่งนี้จะทำให้ข้อผิดพลาดของสคริปต์ออกมาได้อย่างสวยงามยิ่งขึ้น

ฉันคิดว่านี่เป็นตัวเลือกที่ดีที่สุดเพราะสามารถใช้ได้กับทุกระบบปฏิบัติการ * nix เช่น Solaris, Linux และอื่น ๆ

#!/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}

ฉันพบว่าบนหนึ่งในเครื่อง Solaris 10 ของฉันstatไม่พบ นั่นอาจเป็นปัญหากับการกำหนดค่าของฉัน


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.