Comment inspecter les autorisations de groupe d'un fichier

9

Je voudrais inspecter les autorisations de groupe d'un fichier à partir d'un script bash. Plus précisément, je dois vérifier si un fichier contient le bit inscriptible de groupe.

C'est ça. Aussi simple que cela. Toutefois:

  1. J'ai également besoin que ce soit portable.
  2. test -w <file ne me dira pas si c'est accessible en groupe.
  3. La sortie de ls -ldest agréable pour les humains, mais pas si sûre des scripts. Techniquement, je pourrais analyser la sortie de manière drwxrwxr-xà extraire les bits de groupe, mais cela semble fragile.
  4. L'interface pour statest totalement incompatible entre OS X et d'autres systèmes.
  5. find <file> -perm ... ne peut pas être la réponse?
mislav
la source
Devez-vous vérifier le bit d'autorisation de groupe, ou devez-vous vérifier si un groupe spécifique a des autorisations d'écriture? Le groupe (ou l'utilisateur) peut avoir une autorisation d'écriture via une ACL.
Gilles 'SO- arrête d'être méchant'
Juste le bit d'autorisation de groupe. Aucun groupe spécifique n'est pertinent.
mislav

Réponses:

8

Méthode n ° 1 - stat

Vous pouvez utiliser la statcommande pour obtenir les bits d'autorisation. statest disponible sur la plupart des Unix (OSX, BSD, pas AIX d'après ce que je peux trouver). Cela devrait fonctionner sur la plupart des Unix, sauf OSX et BSD d'après ce que je peux trouver.

$ stat -c "%a" <file>

Exemple

$ ls -l a
-rw-rw-r-- 1 saml saml 155 Oct  6 14:16 afile.txt

Utilisez cette commande:

$ stat -c "%a" afile.txt
664

Et utilisez un simple greppour voir si le mode d'autorisation des groupes est 6 ou 7.

$ stat -c "%a" afile.txt | grep ".[67]."

Pour Mac OS X et BSD vous auriez besoin d'utiliser cette forme de stat, stat -f(ou peut - être stat -x), et d' analyser en conséquence. Étant donné que les options de statsont différentes, vous pouvez encapsuler cette commande dans une lsb_release -acommande et appeler la version appropriée en fonction du système d'exploitation. Pas idéal mais réalisable. Sachez que cela lsb_releasen'est disponible que pour les distributions Linux, donc une autre alternative devrait être conçue pour tester d'autres systèmes d'exploitation Unix.

Méthode n ° 2 - trouver

Je pense que cette commande pourrait vous servir mieux. J'utilise findet le printfcommutateur.

Exemple

$ find a -prune -printf '%m\n'
664

Méthode n ° 3 - Perl

Perl pourrait être un moyen plus portable de le faire en fonction des systèmes d'exploitation que vous essayez de couvrir.

$ perl -le '@pv=stat("afile.txt"); printf "%04o", $pv[2] & 07777;'
0664

REMARQUE: ce qui précède utilise la stat()fonction de Perl pour interroger les bits du système de fichiers.

Vous pouvez rendre cela plus compact en renonçant à utiliser un tableau @pv, et en traitant stat()directement la sortie de :

$ perl -le 'printf "%04o", (stat("a"))[2] & 07777;'
0664
slm
la source
Je pense que vous avez raté son point 4. La statcommande varie considérablement entre les différents systèmes et n'est pas portable.
jordanm
@jordanm - merci je l'ai vu, je cherchais une alternative. Je pense qu'il find . -printfpeut le faire mais ne peut pas déterminer s'il est disponible sur OSX 'find.
slm
1
Je ne l'ai pas trouvé non plus référencé dans le guide POSIX2008, donc je suis enclin à être d'accord. Je ne suis sûr d'aucune autre méthode. Je pense que vous devez mordre la balle ici et détecter quel système d'exploitation et appeler l'approp. semble être la meilleure approche.
slm
1
Je ne pouvais pas non plus penser à une méthode utilisant un utilitaire shell standard. C'est pourquoi ma réponse utilise perl.
jordanm
1
@jordanm - grands esprits. Je travaillais aussi sur une solution Perl 8-)
slm
1

Une option consiste à utiliser perl, qui sera portable partout perlest disponible. Il est difficile de trouver un système Unix sans lui. Voici un exemple de la façon dont il peut être intégré dans un script shell:

if perl -e 'use Fcntl ":mode"; exit( ((stat("file.txt"))[2] & S_IWGRP) >> 3)'; then
    echo "file is group writable"
else
    echo "file is not group witeable"
fi

Des perlexemples similaires peuvent être trouvés dans le stat perldoc .

jordanm
la source
1

J'ai fini par lsanalyser:

is_group_writable() {
  local ls="$(ls -ld "$1")"
  [ "${ls:5:1}" = "w" ]
}

Je suis reconnaissant pour la réponse détaillée de @ slm, mais aucune des autres méthodes n'est aussi simple. La statméthode m'obligerait à écrire au moins deux invocations différentes pour couvrir OS X, et même après cela, elle retourne la représentation octale à laquelle je dois encore appliquer l'arithmétique. La méthode Perl est OK mais nécessite que je démarre un interpréteur pour une tâche aussi simple, et je voudrais rester simple et utiliser uniquement des utilitaires posix.

mislav
la source
2
Vous utilisez bash, pas seulement POSIX. Dans POSIX:perms=$(ls -ld -- "$1"); perms=${perms%% *}; case $perms in ?????w????) …
Gilles 'SO- arrête d'être méchant'
0
FILE="filename";G=$(stat -c '%a' ${FILE} | cut -c2);
if [ $G -gt 5 ];then   echo "Group write is set on ${FILE}";fi

Tous les outils Unix / Linux standard.

Je suppose qu'il est POSSIBLE d'avoir un groupe d'écriture, mais pas de groupe de lecture. Dans cette possibilité, il s'agirait soit d'une déclaration de cas 2 | 3 | 6 | 7), soit d'un grep '[2 | 3 | 6 | 7]'.

Doc
la source