Ответы:
На 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>