Comment puis-je obtenir des autorisations de fichier octales à partir de la ligne de commande?

373

Il existe une commande chmod pour définir les autorisations de fichier, mais puis-je obtenir les autorisations de fichier en mode octal (tel que 755) à partir de la ligne de commande?

Anwar
la source
2
Pour les personnes comme moi qui ont atterri accidentellement sur cette page mais qui cherchaient en fait à savoir comment faire cela sur Mac: stackoverflow.com/a/14855227/470749
Ryan
2
stat --format "%A" $FILEvous donne le drwxr-x---format lisible par l'homme . qui peut ou peut ne pas être utile.
Trevor Boyd Smith

Réponses:

535

Tu peux essayer

stat -c "%a %n" *

Remplacez-le *par le répertoire approprié ou par le nom de fichier exact à examiner.

De la page de manuel de stat ,

-c  --format=FORMAT
          use  the  specified  FORMAT instead of the default; output a newline after
          each use of FORMAT
%a     Access rights in octal
%n     File name

Usage:

  • Avec des fichiers:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
    
  • Avec des dossiers:

    $ stat -c "%a %n" ./Documents/
    755 ./Documents/
    

(Référence)

jokerdino
la source
57
sur mac os, utilisez stat -f '%A %a %N' *(crédit: geeklog.adamwilson.info/article/58/… )
s2t2
1
Si vous êtes plus à l'aise avec ls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends
2
@usandfriends en boucle sur la sortie de lsest une mauvaise idée. Si vous voulez vraiment utiliser une boucle, vous pouvez le fairefor f in *; do stat "%a %n" "$f"; done
Tom Fenech
1
Pourquoi sur Mac, tout est légèrement modifié (même sous Unix iso utils)? Y a-t-il une raison réelle à cela?
Vassilis
2
S'il te plaît, @hackel, dis-nous ce que tu ressens vraiment. lol!
MikeSchinkel
44

Les autorisations de fichiers sous Linux peuvent être affichées au format octal à l’aide de la commande Linux stat.

Appuyez simplement sur Ctrl+ Alt+ Tsur votre clavier pour ouvrir Terminal. Lorsqu'il s'ouvre, accédez au répertoire dans lequel vous souhaitez rechercher les autorisations de fichiers en mode octal.

stat -c '%A %a %n' *

% A Droits d'accès sous forme lisible par l'homme

% a Droits d'accès en octal

% n Nom du fichier

Nombres octaux et autorisations

Vous pouvez utiliser un nombre octal pour représenter le mode / permission:

r: 4
w: 2
x: 1

Par exemple, pour le propriétaire de fichier, vous pouvez utiliser le mode octal comme suit. L'autorisation de lecture, d'écriture et d'exécution (complète) sur un fichier en octal est égale à 0 + r + w + x = 0 + 4 + 2 + 1 = 7

Seules les autorisations de lecture et d’écriture sur un fichier en octal sont 0 + r + w + x = 0 + 4 + 2 + 0 = 6

Seules les autorisations de lecture et d'exécution sur un fichier en octal sont 0 + r + w + x = 0 + 4 + 0 + 1 = 5

Utilisez la méthode ci-dessus pour calculer l'autorisation pour le groupe et les autres. Supposons que vous souhaitiez accorder une autorisation complète au propriétaire, une autorisation de lecture et d'exécution au groupe et une autorisation de lecture seule à d'autres utilisateurs. Vous devez ensuite calculer l'autorisation comme suit: Utilisateur = r + w + x = 0 + 4 + 2 + 1 = 7 Groupe = r + w + x = 0 + 4 + 2 + 0 = 6 Autres = r + w + x = 0 + 0 + 0 + 1 = 1

L'autorisation effective est 761.

Source: http://kmaiti.blogspot.com/2011/09/umask-concept.html

Mitch
la source
2
Les 0 initiaux représentent aussi un bit spécial: pastebin.com/6ymkFt71
Braiam
36

Comme détaillé dans les autorisations de type «755» avec «ls» par Adam Courtemanche sur AgileAdam.com , vous pouvez créer un alias lso qui agit comme si, ls -lmais traite légèrement la sortie 1 pour afficher les autorisations également en octal. Cela ajoute une colonne de tête indiquant les autorisations octales à deux chiffres à trois chiffres . Tel qu'écrit, cela fonctionne pour la plupart des fichiers et des répertoires, mais ne fonctionne pas correctement si les bits sticky ou setuid / setgid sont définis. 3

alias lso="ls -alG | awk '{k=0;for(i=0;i<=8;i++)k+=((substr(\$1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\" %0o \",k);print}'"

Comme le souligne Techtonik , cela présente toutefois un grave inconvénient . Vous ne pouvez pas transmettre d'arguments à cet lsoalias comme à la lscommande , car ils sont considérés comme des arguments supplémentaires awk. Ainsi, vous ne pouvez pas exécuter lsosur un fichier ou un répertoire spécifique, vous ne pouvez pas non plus transmettre d’option (comme -F, ou --color) à lso.


Le correctif consiste à définir lso une fonction plutôt qu'un alias.

lso() { ls -alG "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Si vous essayez cela interactivement dans votre shell, exécutez unalias lsopour supprimer l'alias - vous pouvez le faire avant ou après avoir défini la fonction. Si vous le placez dans un fichier source, tel que ~/.bashrc, il suffit de supprimer la aliasligne et d'ajouter la définition de la fonction.

Pourquoi ça marche? Contrairement aux alias, les fonctions du shell bash peuvent prendre des paramètres de position , c'est -à- dire des arguments de ligne de commande . "$@"étend à la liste complète des arguments , entraînant le passage des arguments à la lsofonction ls. (Contrairement à une définition d'alias, aucun corps de fonction n'est cité; il était donc nécessaire de supprimer les \caractères avant $et ".)

Étant donné que vous pouvez transmettre des options à lsoune fonction définie de cette manière, vous souhaiterez peut-être supprimer les options -aet -Gde la définition. Vous pouvez les transmettre manuellement dans les cas où vous le souhaitez. ( L' -loption est requise pour des détails comme les autorisations de fichiers à afficher du tout , donc il n'y a aucun avantage à le retirer.)

lso() { ls -l "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Merci à techtonik pour souligner la limitation dans la définition lsocomme un alias, me motive ainsi à étendre ce poste avec du matériel de faire une fonction à la place.


1 On peut noter que cela semble bafouer la règle générale selon laquelle il ne faut pas analyser la sortie dels . lsproduit une sortie très lisible par l'homme; cela introduit des particularités et des limitations qui le rendent généralement inadapté comme entrée pour d'autres commandes. Dans ce cas, nous analysons lspuisque nous souhaitons conserver le comportement exact dels notre seul changement.

2 Une limite de cet alias, qui s'applique également à la version de fonction indiquée ci-dessous, et qui peut être considérée comme un bogue, est qu'elle n'affiche que trois chiffres octaux, même lorsque le quatrième chiffre est zéro. Comme jfmercer l' a fait remarquer à juste titre , les chiffres octaux affichés ici ne reflètent pas le bit collant s'il est présent, ni les bits setuid ou setgid.

3 Plus sérieusement que simplement ne pas montrer le quatrième chiffre octal est que cette méthode suppose qu'ils ne sont pas définies, et si elles sont - si vous voyez t, sou Sdans la chaîne d'autorisation - alors vous devriez ne pas tenir compte des chiffres octaux . Ceci parce que les bits sont déduits de la chaîne d'autorisations d'une manière qui ne prend pas en compte les bits sticky setuid / setgid.

Eliah Kagan
la source
ne fonctionne pas avec les répertoires -awk: read error (Is a directory)
anatoly techtonik
@techtonik Merci de l'avoir signalé! J'ai (enfin) mis à jour cette réponse pour y inclure un correctif.
Eliah Kagan
1
Vous pouvez ajouter un --colorparamètre pour afficher les couleurslso() { ls -alG "$@" --color | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }
tagplus5
1
avez-vous découvert une solution au problème persistant de setuid / setgid depuis que vous l'avez publié?
Silvestris
21

En étendant simplement \ simplifiant les réponses précédentes 'stat':

Vous pouvez simplement lancer:

stat <path_to_file>

La sortie contiendra une permission octale avec d'autres informations.



Détails (version et exemple de la statistique):

# stat --version
stat (GNU coreutils) 8.4


[user@localhost ~]# touch /tmp/TEST_PERMISSONS

[user@localhost ~]# chmod 644 /tmp/TEST_PERMISSONS

[user@localhost ~]# stat /tmp/TEST_PERMISSONS
  File: `/tmp/TEST_PERMISSONS'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1010058     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-08-26 18:58:59.000000000 +0300
Modify: 2015-08-26 18:58:59.000000000 +0300
Change: 2015-08-26 18:59:16.000000000 +0300

Notez le: ( 0644 / -rw-r - r--)

Vano
la source
6

Pour la portabilité, vous pouvez utiliser perl:

$ perl -e 'printf "%04o %s\n", (stat)[2] & 07777, $_ for @ARGV' *.txt
0644 1.txt
0644 2.txt
0644 3.txt
0644 4.txt
0600 PerlOneLiner.txt
0664 perl.txt

Si vous voulez remarquer quand une erreur se produit, essayez:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt
cuonglm
la source
2
En plus d'être portable, la solution de @ cuonglm affiche quatre caractères octaux au lieu de trois , indiquant ainsi l'état du «bit collant» souvent oublié.
jfmercer
2

Vous pouvez utiliser findavec l' -printfaction.

lsne montre pas les permissions octales, mais vous pouvez utiliser cette findsolution de contournement:

find path -printf "%m:%f\n"

Par exemple, pour vérifier mon répertoire de vidéos:

$ find Videos -printf "%m:%f\n"
755:Videos

Le %mspécificateur de format indique à l' -printfaction d'imprimer des autorisations octales, tandis que le %fspécificateur de format lui permet d'imprimer le nom de fichier.

Vous pouvez transmettre plusieurs noms de fichiers à find. Vous pouvez même utiliser des globs (par exemple find * -printf "%m:%f\n").

Vous n'êtes pas obligé d'utiliser un test comme -nameou -iname; il suffit de donner le nom des fichiers ou des répertoires qui vous intéressent find. Autrement dit, fournissez leurs noms comme arguments immédiatement après le mot find, comme indiqué ci-dessus.

findvous donne un grand contrôle sur la façon dont il affiche la sortie. Il y a deux modifications en particulier qui pourraient vous être utiles:

  • Par défaut, findrecurses sous répertoires, similaire à ls -R. Si vous ne souhaitez findpas visiter les sous-répertoires des points de départ que vous lui transmettez, vous pouvez les ajouter -maxdepth 0(ou les utiliser -maxdepthavec d'autres valeurs pour indiquer la profondeur à laquelle vous souhaitez aller).

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %faffiche uniquement un nom de fichier, donc s'il findfaut recurse pour obtenir un fichier, vous pourriez ne pas savoir où il se trouve. Pour afficher un chemin commençant par le point de départ du fichier, utilisez %pplutôt.

    $ find /boot -printf "%m:%p\n"
    755:/boot
    644:/boot/initrd.img-4.4.0-92-generic
    600:/boot/System.map-4.4.0-93-generic
    600:/boot/vmlinuz-4.4.0-92-generic
    600:/boot/vmlinuz-4.4.0-93-generic
    ....

Voir man findpour plus d'informations sur l'utilisation de la findcommande.

Une autre méthode ( lset awk)

Ceci peut être utilisé pour lister tous les fichiers de répertoires avec leurs permissions:

ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
             *2^(8-i));if(k)printf("%0o ",k);print}'

C’est essentiellement la même commande que dans le lsopseudonyme d’ Adam Courtemanche , que cette réponse a cité, n’est exécutée qu’en une seule commande. Si vous utilisez cette option une seule fois ou dans de rares cas, vous ne voudrez peut-être pas vous soucier de l'écrire sous forme d'alias ou de fonction shell.

Maythux
la source