Pourquoi certaines valeurs umask ne prennent-elles pas effet?

9

J'essaie de mieux comprendre les autorisations, donc je fais quelques "exercices". Voici une séquence de commandes que j'utilise avec leur sortie respective:

$ umask
0022
$ touch file1
$ ls -l file1
-rw-r--r-- 1 user group 0 Mar 16 12:55 file1
$ mkdir dir1
$ ls -ld dir1
drwxr-xr-x 2 user group 4096 Mar 16 12:55 dir1

Cela est logique car nous savons que les autorisations de fichier par défaut sont 666( rw-rw-rw-) et que les autorisations par défaut des répertoires sont 777( rwxrwxrwx). Si je soustrais la valeur umask de ces autorisations par défaut que j'ai 666-022=644, rw-r--r--pour le file1, il est donc cohérent avec la sortie précédente; 777-022=755,, rwx-r-x-r-xpour le dir1, également cohérent.

Mais si je change le umask de 022la 021ce n'est pas plus.

Voici l'exemple du fichier:

$ umask 0021
$ touch file2
$ ls -l file2
-rw-r--rw- user group 0 Mar 16 13:33 file2

-rw-r--rw-est, 646mais il devrait l'être 666-021=645. Donc, cela ne fonctionne pas selon le calcul précédent.

Voici l'exemple du répertoire:

$ touch dir2
$ ls -ld dir2
drwxr-xrw- 2 user group 4096 Mar 16 13:35 dir2

drwxr-xrw-est 756, 777-021=756. Dans ce cas, le résultat est donc cohérent avec le calcul précédent.

J'ai lu l'homme mais je n'ai rien trouvé sur ce comportement.

Quelqu'un peut-il expliquer pourquoi?

EXPLICATION

Comme indiqué dans les réponses: umaskla valeur de n'est pas mathématiquement soustraite des autorisations de répertoire et de fichier par défaut.

L'opération effectivement impliquée est une combinaison d'opérateurs booléens AND (&) et NOT (!). Donné:

R = autorisations résultantes
D = autorisations par défaut
U = umask actuel

R = D &! U

Par exemple:

666 &! 0053 = 110 110 110 & 
            ! 000 101 011 
             110 110 110 &  
             111 010 100
           = 110 010 100 = 624 = rw - wr--
 
777 &! 0022 = 111 111 111 & 
            ! 000 010 010
             111 111 111 &  
             111 101 101
           = 111 101 101 = 755 = rwxr - xr-x 

POINTE

Un moyen simple de connaître rapidement les autorisations résultantes (au moins cela m'a aidé) est de penser que nous pouvons utiliser seulement 3 valeurs décimales:

r = 100 = 4 
w = 010 = 2
x = 001 = 1

Les autorisations seront une combinaison de ces 3 valeurs.
" "est utilisé pour indiquer que l'autorisation relative n'est pas donnée.

666 = 4+2+" "   4+2+" "   4+2+" "  = rw rw rw  

Donc, si mon umask actuel est 0053je sais que je supprime les (4+1) autorisations de lecture et d'exécution du groupe et que l'écriture et l'exécution (2+1)des autres entraînent

 4+2     " "+2+" "     4+" "+" "   = 624 = rw--w-r--  

(le groupe et les autres n'avaient déjà pas de permission d'exécution)

ikeDiM
la source

Réponses:

26

umaskest un masque , ce n'est pas une valeur soustraite. Donc:

  • mode 666, masque 022: le résultat est 666 & ~ 022, soit 666 & 755, qui est 644;
  • mode 666, masque 021: le résultat est 666 & ~ 021, soit 666 & 756, qui est 646.

Pensez aux morceaux impliqués. 6 dans un mode signifie que les bits 1 et 2 sont définis, lus et écrits. 2 dans un masque masque le bit 1, le bit d'écriture. 1 dans un masque masque le bit 0, le bit d'exécution.

Une autre façon de représenter cela est de regarder les autorisations sous forme de texte. 666 est rw-rw-rw-; 022 est ----w--w-; 021 est ----w---x. Le masque supprime ses bits définis du mode, donc rw-rw-rw-masqué par ----w--w-devient rw-r--r--, masqué par ----w---xdevient rw-r--rw-.

Stephen Kitt
la source
11

Vous devez penser en binaire et non en décimal. Plus précisément, il existe trois nombres binaires à 3 bits: un pour Propriétaire, Groupe et Autre. Chacun avec des valeurs allant de 000 à 111 (0-7 en décimal).

par exemple rw-rw-rw (666) est 110 110 110.

La umaskvaleur est un masque spécifiant quels bits seront activés ou désactivés (1 ou 0) lors de la création d'un nouveau fichier ou répertoire. par exemple 022 décimal est 000 010 010 binaire, tandis que 021 décimal est 000 010 001

Les bits d'autorisation sont ET-ed avec le umask nié pour arriver à la valeur finale. "nié" signifie que tous les bits sont inversés, c'est-à-dire tous les 1 basculés à 0, et vice-versa. par exempleNOT 022 (000 010 010) = 755 (111 101 101)

Exemple: 666 & !022 = 644. En binaire, c'est:

  Owner  Group  Other     mode
   110    110    110      666 
&  111    101    101      755   (this is the negated 022)
   ---    ---    ---      ---
   110    100    100      644

Aussi 777 & !022 = 755:

  Owner  Group  Other     mode
   111    111    111      777 
&  111    101    101      755
   ---    ---    ---      ---
   111    101    101      755

Notez comment la valeur finale de chaque bit ne peut être 1 si elle est 1 à la fois la valeur d'autorisation initiale (666 ou 777) et dans le umask niée. Si l'un d'eux est 0, le résultat est 0. Autrement dit, 1 & 1 = 1 , tandis que 1 & 0 = 0 .


À strictement parler, il existe un quatrième nombre binaire à 3 bits pour les bits setuid, setgid et sticky. C'est pourquoi vous voyez souvent des autorisations et des masques spécifiés avec un 0 en tête (ou un autre nombre en tête de 0 à 7). par exemple 0777 ou 2755.

cas
la source
2
Eh bien, techniquement, c'est octal, pas décimal, mais cela ne change pas vraiment le cœur de la réponse.
David Z
@DavidZ: OP pensait que c'était décimal (voir l'exemple de soustraction dans le Q), ce qui est vraisemblablement à quoi cas faisait référence.
Courses de légèreté en orbite
1
@Lightness les exemples de soustraction donnés par l'OP fonctionnent qu'ils soient octaux ou décimaux, étant donné qu'aucun chiffre n'atteint 8 et qu'il n'y a jamais besoin d'un report. Je suis d'accord qu'il est possible que l'OP pense en décimal, mais rien dans la question ne le prouve.
Stephen Kitt
@StephenKitt: On dirait que mon doigt a dû glisser sur le clavier lorsque j'écrivais des exemples dans calc.exe pour le prouver 😂
Courses de légèreté en orbite
1
@cas oui, je n'étais pas en désaccord avec cette partie (c'est aussi la base de ma réponse), juste avec l'affirmation de Lightness que l'OP calculait en décimal plutôt qu'en octal.
Stephen Kitt