Cloner la propriété et les autorisations d'un autre fichier?

125

Existe-t-il une commande ou un indicateur permettant de cloner la propriété de l'utilisateur / groupe et les autorisations sur un fichier à partir d'un autre fichier? Rendre les permanentes et la propriété exactement celles d'un autre fichier?

utilisateur394
la source

Réponses:

175

Sur GNU / Linux chownet chmodavoir une --referenceoption

chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
enzotib
la source
1
Pourriez-vous vous référer à cette réponse (et probablement la citer) pour répondre à ma question: unix.stackexchange.com/questions/44253/… ? Je pense que je serai un excellent ajout et j'aimerais beaucoup y trouver des votes positifs.
Grzegorz Wierzowiecki
@ GrzegorzWierzowiecki: cette question devrait probablement être close, mais elle est un peu différente de celle-ci et a déjà des réponses, alors je ferais mieux de ne rien faire.
enzotib
Comme vous le souhaitez et suggérez. Merci pour l'aide, je n'ai jamais mis l'accent sur le --referenceparamètre d' chmodet chownavant :).
Grzegorz Wierzowiecki
12

Sur tout UNIX avec des utilitaires GNU, tels que Linux (non intégré) ou Cygwin, vous pouvez utiliser chmod --referenceetchown --reference .

Si votre système possède des ACL , essayez les commandes ACL getfaclet setfacl. Ces commandes diffèrent légèrement d’un système à l’autre, mais sur beaucoup d’entre elles, vous pouvez utiliser getfacl other_file | setfacl -bnM - file_to_changepour copier les autorisations. Cela ne copie pas la propriété. vous pouvez le faire avec une analyse minutieuse de ls -l other_file, en supposant que vous n'avez pas de nom d'utilisateur ou de groupe contenant des espaces.

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
Gilles
la source
1
ACL doit être installé et le système de fichiers monté avec ACL activé.
enzotib
2
@enzotib Au moins sur Linux, les outils de LCA fonctionneront pour copier les autorisations (mais pas la propriété) même si les systèmes de fichiers source et cible ne prennent pas en charge les ACL.
Gilles
7

Est-ce qu'une commande bash basée sur la réponse de Matteo :)

Code:

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

Usage:

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

Mjlescano
la source
5
Egad! Où avez-vous appris à dire ${*:2}? Ne refais plus jamais ça! Cela échouera si l'un des noms de fichiers contient un espace (ou des onglets). Utilisez "${@:2}". Aussi, utilisez "$1"plutôt que juste $1.
G-Man
chmod "$(stat -c '%a' "$fromfile")" tofiledans GNU Coreutils, mais vous pourriez aussi bien l'utiliser --referencedans ce cas puisque l' statutilitaire de la CLI n'est pas POSIX, il est même indiqué que pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.htmlthat ls -l ne le coupera pas: "La sortie de ls (avec l'option -l et les options associées) contient des informations pouvant être utilisées de manière logique par des utilitaires tels que chmod et touch pour restaurer les fichiers dans un état connu. facilement traduit dans un format utilisable. "
Ciro Santilli a annoncé le
5

Si vous n’utilisez pas de système avec chmod / chown de GNU (qui supporte l’ --referenceoption), vous pouvez essayer d’analyser la sortie dels -l

Voici un petit script pour chmod(si vous voyez un fichier qui supporte les expressions rationnelles étendues, elles pourraient être écrites de manière beaucoup plus lisible ...)

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

MISE À JOUR :

C'est encore plus simple avec stat:

chmod $( stat -f '%p' ${reference} ) ${files}
Matteo
la source
2
Au lieu d'analyser la ls -lsortie, vous pouvez analyser la statsortie.
Jfg956
@ jfgagne: merci, ça a du sens, je ne sais pas pourquoi je n'y avais pas pensé tout de suite. J'ai mis à jour la réponse
Matteo
1
Vous utilisez la statsyntaxe * BSD ici. Votre chmod $(stat ...)commande ne fonctionnera pas car à elle %pseule génère trop d'informations pour * BSD chmod, utilisez-les %Lppour générer uniquement les bits u / g / o. Quelque chose de légèrement plus élaboré serait nécessaire pour les bits sticky / setuid / setgid.
mr.spuratic
0

Je voulais ajouter un ajustement au script de Matteo . Une boucle for doit être utilisée pour valider l'existence des fichiers avant d'exécuter la commande chmod sur ceux-ci. Cela laissera le script sortir plus gracieusement.

Je pense que c'est la meilleure option car elle peut être utilisée pour tous les systèmes d'exploitation * nix, tels que Solaris, Linux, etc.

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

J'ai trouvé que sur l'une de mes machines Solaris 10, statn'a pas été trouvé. Cela pourrait cependant être un problème avec ma configuration.

David
la source
0

Cela fonctionne pour moi:

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

utilisateur172554
la source