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ó 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:
Trên GNU / Linux chown
và chmod
có một --reference
tùy chọn
chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
--reference
tham số của chmod
và chown
trước đó :).
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 --reference
vàchown --reference
.
Nếu hệ thống của bạn có ACL , hãy thử các lệnh ACL getfacl
và setfacl
. 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
Đã 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>...
${*: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
.
chmod "$(stat -c '%a' "$fromfile")" tofile
trong GNU Coreutils, nhưng bạn cũng có thể sử dụng --reference
trong trường hợp đó vì stat
tiệ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. "
Nếu bạn không sử dụng hệ thống với chmod / chown của GNU (hỗ trợ --reference
tù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}
ls -l
đầu ra, bạn có thể phân tích stat
đầu ra.
stat
cú pháp * BSD tại đây. chmod $(stat ...)
Lệnh của bạn sẽ không hoạt động vì %p
mộ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.
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, stat
khô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ù.
Điều này làm việc cho tôi:
cp -p --attributes-only <from> <to>