Владение клоном и разрешения из другого файла?

125

Есть ли команда или флаг для клонирования владельца / разрешения пользователя / группы на файл из другого файла? Чтобы сделать завивки и владения точно таковыми из другого файла?

user394
источник

Ответы:

175

На GNU / Linux chownи chmodесть --referenceопция

chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
enzotib
источник
1
Не могли бы вы сослаться на этот ответ (и, вероятно, процитировать его) как ответ на мой вопрос: unix.stackexchange.com/questions/44253/… ? Я думаю, что я буду отличным дополнением, и я бы с удовольствием нашел там за него голоса "за".
Гжегож Вежовецкий
@GrzegorzWierzowiecki: возможно, этот вопрос должен быть закрыт, но он немного отличается от этого и уже имеет ответы, так что мне лучше ничего не делать.
энзотиб
Как пожелаете и предложите. Спасибо за помощь, я никогда не обращал внимания на --referenceпараметры chmodи chownраньше :).
Гжегож Вежовецкий
12

На любом 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
жилль
источник
1
У вас должен быть установлен ACL и файловая система с включенным ACL.
энзотиб
2
@enzotib По крайней мере в Linux инструменты ACL будут работать для копирования разрешений (но не владения), даже если исходная и целевая файловые системы не поддерживают ACL.
Жиль
7

Сделал команду bash на основе ответа Маттео :)

Код:

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

Использование:

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

mjlescano
источник
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.htmlthat ls -l не будет сокращать это: «Вывод ls (с опциями -l и соответствующими параметрами) содержит информацию, которая логически могла бы использоваться утилитами, такими как chmod и touch, для восстановления файлов до известного состояния. Однако эта информация представлена ​​в формате, который не может использоваться этими утилитами напрямую или легко переводится в формат, который можно использовать ".
Сиро Сантилли 新疆 改造 中 at 法轮功 六四 事件
5

Если вы не используете систему с 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}
Matteo
источник
2
Вместо того, чтобы анализировать ls -lвывод, вы могли бы проанализировать statвывод.
jfg956
@jfgagne: спасибо имеет смысл, я не знаю, почему я вообще не думал об этом. Я обновил ответ
Маттео
1
Вы используете * BSD statсинтаксис здесь. Ваша chmod $(stat ...)команда не будет работать, потому что %pсама по себе выводит слишком много информации для * BSD chmod, используйте %Lpдля вывода только биты u / g / o. Для битов sticky / setuid / setgid потребуется нечто более сложное.
mr.spuratic
0

Я хотел добавить корректировку в сценарий Маттео . Цикл 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не был найден. Это может быть проблемой с моей конфигурацией, хотя.

Дэвид
источник
0

Это работает для меня:

cp -p --attributes-only <from> <to>

user172554
источник