Ответы:
На GNU / Linux chownи chmodесть --referenceопция
chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
--referenceпараметры chmodи chownраньше :).
На любом Unix с утилитами GNU, такими как (не встроенный) Linux или Cygwin, вы можете использовать chmod --referenceиchown --reference .
Если ваша система имеет ACL , попробуйте команды 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
Сделал команду bash на основе ответа Маттео :)
Код:
chmod $( stat -f '%p' "$1" ) "${@:2}"
Использование:
cp-permissions <from> <to>...
${*:2}? Никогда больше так не делай! Это не удастся, если любое из имен файлов содержит пробел (или вкладки). Используйте "${@:2}". Кроме того, используйте "$1"вместо просто $1.
chmod "$(stat -c '%a' "$fromfile")" tofileв GNU Coreutils, но вы могли бы также использовать --referenceв этом случае, поскольку statутилита CLI не POSIX, она даже говорит, что pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.htmlthat ls -l не будет сокращать это: «Вывод ls (с опциями -l и соответствующими параметрами) содержит информацию, которая логически могла бы использоваться утилитами, такими как chmod и touch, для восстановления файлов до известного состояния. Однако эта информация представлена в формате, который не может использоваться этими утилитами напрямую или легко переводится в формат, который можно использовать ".
Если вы не используете систему с GNU chmod / chown (которая поддерживает эту --referenceопцию), вы можете попытаться проанализировать выводls -l
Вот небольшой скрипт для chmod(если у вас есть видение, которое поддерживает расширенные регулярные выражения, они могут быть написаны гораздо более читабельным способом ...)
#!/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}
ls -lвывод, вы могли бы проанализировать statвывод.
statсинтаксис здесь. Ваша chmod $(stat ...)команда не будет работать, потому что %pсама по себе выводит слишком много информации для * BSD chmod, используйте %Lpдля вывода только биты u / g / o. Для битов sticky / setuid / setgid потребуется нечто более сложное.
Я хотел добавить корректировку в сценарий Маттео . Цикл 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не был найден. Это может быть проблемой с моей конфигурацией, хотя.
Это работает для меня:
cp -p --attributes-only <from> <to>