web-dev-qa-db-fra.com

Besoin de corriger les autorisations de fichier dans le répertoire de base d'un utilisateur

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

Sur une machine Ubuntu Linux, un groupe de fichiers a été copié sur un disque USB avec des autorisations complètes 777 (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, de sorte qu'aucun d'entre eux n'a besoin d'être exécutable. Si le bit de répertoire est défini, il a besoin d'exécution, d'autres sages, il suffit de répondre à l'utilisateur et au groupe, à lire et à écrire.

Je pensais que cela valait la peine de vérifier si un tel utilitaire existe avant de pirater un script shell :)

27
mlambie

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
52
freiheit

trouver peut faire le tour seul avec -exec:

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

pour empêcher la recherche d'un chmod pour chaque entrée:

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

(Cela appelle efficacement Chmod une fois avec la liste de tous les fichiers sous forme de paramètres plutôt que d'un chmod par fichier)

15
ThorstenS

Cette réponse ne résoudra pas votre problème, mais une personne peut trouver utile pour un problème similaire où les fichiers ont moins d'autorisation qu'autrement.

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

La magie est la permission X, plutôt que x. Le chmod Manpage le décrit ainsi:

exécuter/rechercher uniquement si le fichier est un répertoire ou a déjà exécuté la permission pour certains utilisateurs

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

8
David Pashley

J'ai fait un script de bash vraiment simple l'autre jour parce que je devais réparer les autorisations. Pourquoi n'y a-t-il pas d'utilité formelle pour réinitialiser les autorisations de base, de non-racine, de fichier et de dossier?

Le script utilise la recherche de 755 tous les dossiers et 644 bibliothèques. Il teste ensuite chaque fichier avec loyage pour voir s'il a un en-tête binaire elfe. Sinon, il scanne dans les deux premiers personnages pour Shebang #!. Il 755 Ces instances et 644 tout le reste après avoir vérifié pour voir si le fichier a déjà la permission correspondante.

Les cas spéciaux sont traités avec une exception comme le *.bak Pour que les fichiers soient ignorés.

#!/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
1
noabody

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

#!/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
1
Marcs

J'ai trouvé une solution C-shell simplifiée. Cela pourrait ne pas être complètement tromper la preuve mais devrait fonctionner pour la plupart des annuaires. Il suppose que les travaux de commande Unix 'Fichier' utilisent des fichiers Exec pour les réinitialiser aux autorisations d'exécutant:

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
0
K. Donovan

Une alternative, qui ne répond pas exactement à la demande initiale, mais est plus probable ce que l'OP entend, est de spécifier les autorisations symboliquement. E.G., je suppose que OP veut "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 symbolique de l'autorisation.

  • o-w est "Supprimer l'accès à l'écriture du public" ("O" - Autres, "-" - Supprimer, "w" - écrire)
  • a-X est "Supprimer exécuter pour tout le monde sur les fichiers uniquement" ("A" - Tous, "-" - Supprimer, "x" - Exécuter)

L'écriture de cette façon plutôt que de régler explicitement "0664", vous évitez de permettre accidentellement des autorisations supplémentaires aux fichiers précédemment verrouillés. E.G., si un fichier était 0770, il ne deviendra pas 0664 par erreur.

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

chmod --recursive o-w $dir

Faire la deuxième exigence:

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

Ou faire les deux:

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

Si vous utilisez SSH, c'est une bonne idée de ne pas modifier ~/.ssh autorisations.

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
0
Tombart