Besoin de corriger les autorisations de fichiers dans le répertoire personnel d'un utilisateur

24

Quelqu'un a-t-il un outil ou un script qui corrige récursivement les autorisations de fichier sur un répertoire?

Sur une machine Ubuntu Linux, un tas de fichiers ont été copiés sur un disque USB avec des autorisations 777 complètes (utilisateur, groupe, autre - lecture, écriture, exécution) par erreur. Je veux les remettre dans le répertoire de l'utilisateur corrigé.

Les répertoires doivent être 775 et tous les autres fichiers peuvent être 664. Tous les fichiers sont des images, des documents ou des MP3, donc aucun d'entre eux n'a besoin d'être exécutable. Si le bit de répertoire est défini, il doit être exécuté, sinon il suffit de l'utilisateur et du groupe, en lecture et en écriture.

J'ai pensé qu'il valait la peine de vérifier si un tel utilitaire existe avant de pirater un script shell :)

mlambie
la source
en voici une que j'ai faite plus tôt: http://timwise.blogspot.com/2008/08/reseting-home-folder-permissions-in.html
Tim Abell

Réponses:

51

Cela devrait faire l'affaire:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664
freiheit
la source
1
+1 pour l'utilisation de -print0 / xargs -0 :-).
sleske
14

find peut faire l'affaire tout seul avec -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

pour empêcher find de générer un chmod pour chaque entrée:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(cela appelle effectivement chmod une fois avec la liste de tous les fichiers en tant que paramètres plutôt qu'un chmod par fichier)

ThorstenS
la source
6
Plus lent que l'utilisation de xargs, car vous bifurquez un chmod pour chaque fichier, où xargs exécutera un processus chmod avec autant de fichiers qu'il peut tenir sur une ligne de commande. Sur un très grand arbre, cela peut faire une bonne différence.
David Pashley
1
En outre, print0 / xargs -0 gérera même les noms de fichiers très étranges; pas si sûr de trouver -exec.
sleske
8

Cette réponse ne résoudra pas votre problème, mais quelqu'un pourrait la trouver utile pour un problème similaire où les fichiers ont moins d'autorisations qu'ils ne devraient.

# chmod -R . u=rwX,g=rX,o=rX

La magie est l'autorisation X, plutôt que x. La page de manuel chmod le décrit ainsi:

exécuter / rechercher uniquement si le fichier est un répertoire ou dispose déjà d'une autorisation d'exécution pour un utilisateur

Cela ne convient pas dans votre cas, car vos fichiers ont une autorisation d'exécution, correspondra donc au deuxième test.

David Pashley
la source
1
g devrait être rwX pour 775 et 664.
aventurin
1

J'ai fait un script à partir de la solution de freiheit, il ajoute une vérification de base des arguments.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644
Marcs
la source
Bonne idée. Cependant, la deuxième ligne renvoie une erreur lorsque la cible est un répertoire: chmod: missing operand after ‘0644’. Puis-je suggérer d'encapsuler les instructions find avec une vérification pour voir si la cible existe? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Underverse
C'est presque correct; mais si la cible est un répertoire, vous avez oublié de chmoder les fichiers qu'il contient, et s'il s'agit d'un fichier, il vous suffit de chmoder ce fichier uniquement.
sean
0

Dans le cas où vous utilisez ssh, c'est une bonne idée de ne pas modifier les ~/.sshautorisations.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664
Tombart
la source
0

J'ai fait un script bash très simple l'autre jour parce que je devais corriger les autorisations. Pourquoi n'y a-t-il pas un utilitaire formel pour réinitialiser les autorisations de base, non root, de fichiers et de dossiers?

Le script utilise 755 pour trouver tous les dossiers et 644 bibliothèques. Il teste ensuite chaque fichier avec readelf pour voir s'il a un en-tête elf binaire. Sinon, il recherche les shebang dans les deux premiers caractères #!. Il 755 ces instances et 644 tout le reste après avoir vérifié si le fichier a déjà l'autorisation correspondante.

Les cas spéciaux sont traités avec une exception comme le *.bakpour les fichiers à ignorer.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi
noabody
la source
0

J'ai trouvé une solution C-shell simplifiée. Cela peut ne pas être complètement infaillible mais devrait fonctionner pour la plupart des répertoires. Il suppose que la commande "file" d'Unix fonctionne et trouve les fichiers exec pour les réinitialiser aux autorisations exec:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775
K. Donovan
la source
1
Cela ne se contente pas de répéter certaines des réponses, il introduit une erreur et des fonctionnalités que l'OP n'a pas demandées.
RalfFriedl
0

Une alternative, qui ne répond pas exactement à la demande d'origine, mais qui correspond plus vraisemblablement à l'intention de l'OP, consiste à spécifier symboliquement les autorisations. Par exemple, je suppose que OP souhaite "supprimer l'accès en écriture pour le public et supprimer l'autorisation exécutable de tous les fichiers".

Cela est possible si vous utilisez la représentation d'autorisation symbolique.

  • ow est "supprimer l'accès en écriture du public" ("o" - autres, "-" - supprimer, "w" - écrire)
  • ax est "supprimer exécuter pour tout le monde sur les fichiers uniquement" ("a" - tous "," - "- supprimer," x "- exécuter)

En l'écrivant de cette façon au lieu de définir explicitement «0664», vous évitez d'autoriser accidentellement des autorisations supplémentaires aux fichiers qui ont été précédemment verrouillés. Par exemple, si un fichier était 0770, il ne deviendra pas 0664 par erreur.

Pour faire la première exigence, vous pouvez simplement utiliser chmod:

chmod --recursive o-w $dir

Pour effectuer la deuxième exigence:

find $dir -type f -exec chmod a-x {} +

Ou pour faire les deux:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
chutz
la source