Bản quyền sở hữu và quyền từ một tập tin khác?


125

Có một lệnh hoặc cờ để sao chép quyền sở hữu và quyền của người dùng / nhóm trên một tệp từ một tệp khác? Để làm cho perms và quyền sở hữu chính xác những người của một tập tin khác?

Câu trả lời:


175

Trên GNU / Linux chownchmodcó một --referencetùy chọn

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

1
Bạn có thể tham khảo câu trả lời này (và có thể trích dẫn nó) như câu trả lời cho câu hỏi của tôi: unix.stackexchange.com/questions/44253/ Lỗi ? , Tôi nghĩ rằng tôi sẽ là sự bổ sung tuyệt vời và tôi rất muốn tìm kiếm phiếu bầu cho nó.
Grzegorz Wierzowiecki

@GrzegorzWierzowiecki: có lẽ câu hỏi đó nên được đóng lại, nhưng hơi khác một chút so với điều này và đã có câu trả lời, vì vậy tốt hơn tôi không nên làm gì.
enzotib

Như bạn muốn và đề nghị. Cảm ơn sự giúp đỡ, tôi chưa bao giờ chú ý đến --referencetham số của chmodchowntrước đó :).
Grzegorz Wierzowiecki

12

Trên bất kỳ unix nào với các tiện ích GNU, chẳng hạn như (không nhúng) Linux hoặc Cygwin, bạn có thể sử dụng chmod --referencechown --reference .

Nếu hệ thống của bạn có ACL , hãy thử các lệnh ACL getfaclsetfacl. Các lệnh này khác nhau một chút từ hệ thống này sang hệ thống khác, nhưng trên nhiều lệnh bạn có thể sử dụng getfacl other_file | setfacl -bnM - file_to_changeđể sao chép các quyền. Điều này không sao chép quyền sở hữu; bạn có thể làm điều đó với phân tích cú pháp cẩn thận ls -l other_file, giả sử rằng bạn không có tên người dùng hoặc nhóm chứa khoảng trắng.

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
Bạn nên cài đặt ACL và hệ thống tập tin được gắn với ACL được bật.
enzotib

2
@enzotib Ít nhất trên Linux, các công cụ ACL sẽ hoạt động để sao chép quyền (nhưng không phải quyền sở hữu) ngay cả khi hệ thống tệp nguồn và đích không hỗ trợ ACL.
Gilles

7

Đã thực hiện một lệnh bash dựa trên phản hồi của Matteo :)

Mã số:

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

Sử dụng:

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


5
Egad! Bạn đã học nói ở ${*:2}đâu? Đừng bao giờ làm điều đó một lần nữa! Điều đó sẽ thất bại nếu bất kỳ tên tệp nào chứa không gian (hoặc tab). Sử dụng "${@:2}". Ngoài ra, sử dụng "$1"thay vì chỉ $1.
G-Man

chmod "$(stat -c '%a' "$fromfile")" tofiletrong GNU Coreutils, nhưng bạn cũng có thể sử dụng --referencetrong trường hợp đó vì stattiện ích CLI không phải là POSIX, nó thậm chí còn nói pubs.opengroup.org/onlinepub/9699919799/utilities/ls.htmlthat ls -l sẽ không cắt nó: "Đầu ra của ls (với -l và các tùy chọn liên quan) chứa thông tin có thể được sử dụng một cách hợp lý bởi các tiện ích như chmod và touch để khôi phục các tệp về trạng thái đã biết. Tuy nhiên, thông tin này được trình bày theo định dạng không thể được sử dụng trực tiếp bởi các tiện ích đó hoặc được dễ dàng dịch sang một định dạng có thể được sử dụng. "
Ciro Santilli 心 心 事件

5

Nếu bạn không sử dụng hệ thống với chmod / chown của GNU (hỗ trợ --referencetùy chọn), bạn có thể thử phân tích đầu ra củals -l

Ở đây một tập lệnh nhỏ cho chmod(nếu bạn thấy một chương trình hỗ trợ các biểu thức mở rộng, chúng có thể được viết theo cách dễ đọc hơn nhiều ...)

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

CẬP NHẬT :

Điều này thậm chí còn dễ dàng hơn bằng cách sử dụng stat:

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

2
Thay vì phân tích cú pháp ls -lđầu ra, bạn có thể phân tích statđầu ra.
jfg956

@jfgagne: cảm ơn có ý nghĩa Tôi không biết tại sao tôi không nghĩ về nó ngay từ đầu. Tôi đã cập nhật câu trả lời
Matteo

1
Bạn đang sử dụng statcú pháp * BSD tại đây. chmod $(stat ...)Lệnh của bạn sẽ không hoạt động vì %pmột mình xuất ra quá nhiều thông tin cho * BSD chmod, hãy sử dụng %Lpđể chỉ xuất ra các bit u / g / o. Một cái gì đó phức tạp hơn một chút sẽ được yêu cầu cho các bit dính / setuid / setgid.
mr.spuratic

0

Tôi muốn thêm một điều chỉnh cho kịch bản của Matteo . Một vòng lặp for nên được sử dụng để xác nhận rằng các tệp tồn tại trước khi thực sự chạy lệnh chmod trên chúng. Điều này sẽ cho phép các kịch bản lỗi ra một cách duyên dáng hơn.

Tôi nghĩ rằng đây là tùy chọn tốt nhất vì nó có thể được sử dụng cho tất cả các hệ điều hành * nix, như Solaris, Linux, v.v.

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

Tôi thấy rằng trên một trong 10 máy Solaris của tôi, statkhông tìm thấy. Đó có thể là một vấn đề với cấu hình của tôi mặc dù.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.