Por que alguns valores umask não entram em vigor?

9

Estou tentando entender melhor as permissões, então estou fazendo alguns "exercícios". Aqui está uma sequência de comandos que estou usando com a respectiva saída:

$ 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

Isso faz sentido porque sabemos que as permissões de arquivo padrão são 666( rw-rw-rw-) e as permissões padrão de diretório são 777( rwxrwxrwx). Se eu subtrair o valor umask dessas permissões padrão 666-022=644, tenho rw-r--r--, para o file1, portanto, é coerente com a saída anterior; 777-022=755,, rwx-r-x-r-xpara o dir1, também coerente.

Mas se eu mudar a umask de 022para 021não é mais.

Aqui está o exemplo para o arquivo:

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

-rw-r--rw-é 646mas deveria ser 666-021=645. Portanto, não funciona de acordo com o cálculo anterior.

Aqui está o exemplo para o diretório:

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

drwxr-xrw-é 756, 777-021=756. Portanto, neste caso, o resultado é coerente com o cálculo anterior.

Eu li o homem, mas não encontrei nada sobre esse comportamento.

Alguém pode explicar o porquê?

EXPLICAÇÃO

Conforme indicado nas respostas: umasko valor de não é matematicamente subtraído do diretório padrão e das permissões do arquivo.

A operação efetivamente envolvida é uma combinação de operadores booleanos AND (&) e NOT (!). Dado:

R = permissões resultantes
D = permissões padrão
U = umask atual

R = D &! U

Por exemplo:

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

GORJETA

Uma maneira fácil de conhecer rapidamente as permissões resultantes (pelo menos isso me ajudou) é pensar que podemos usar apenas três valores decimais:

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

As permissões serão uma combinação desses 3 valores.
" "é usado para indicar que a permissão relativa não é fornecida.

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

Portanto, se minha umask atual for 0053sei que estou removendo a (4+1) permissão de leitura e execução do grupo e a gravação e execução (2+1)de outras resultando em

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

(grupo e outro já não tinham permissão de execução)

ikeDiM
fonte

Respostas:

26

umaské uma máscara , não é um valor subtraído. Portanto:

  • modo 666, máscara 022: o resultado é 666 & ~ 022, ou seja , 666 & 755, que é 644;
  • modo 666, máscara 021: o resultado é 666 e ~ 021, ou seja , 666 e 756, que é 646.

Pense nos bits envolvidos. 6 em um modo significa que os bits 1 e 2 são definidos, lidos e gravados. 2 em uma máscara mascara o bit 1, o bit de gravação. 1 em uma máscara mascara o bit 0, o bit de execução.

Outra maneira de representar isso é examinar as permissões em forma de texto. 666 é rw-rw-rw-; 022 é ----w--w-; 021 é ----w---x. A máscara retira seus bits definidos do modo, rw-rw-rw-mascarado por ----w--w-se torna rw-r--r--, mascarado por ----w---xse torna rw-r--rw-.

Stephen Kitt
fonte
11

Você precisa pensar em binário, não decimal. Especificamente, existem três números binários de 3 bits: um para Proprietário, Grupo e Outro. Cada um com valores que variam de 000 a 111 (0-7 em decimal).

por exemplo, rw-rw-rw (666) é 110 110 110.

O umaskvalor é uma máscara que especifica quais bits serão ativados ou desativados (1 ou 0) ao criar um novo arquivo ou diretório. por exemplo, 022 decimal é 000 010 010 binário, enquanto 021 decimal é 000 010 001

Os bits de permissão são AND-ed junto com o umask negado para chegar ao valor final. "negado" significa que todos os bits são invertidos, ou seja, todos os 1s passaram para 0 e vice-versa. por exemploNOT 022 (000 010 010) = 755 (111 101 101)

Exemplo: 666 & !022 = 644. Em binário, é isso:

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

Também 777 & !022 = 755:

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

Note como o valor final de cada bit só pode ser 1 se ele é de 1 em ambos o valor de permissão original (666 ou 777) E na umask negada. Se um deles for 0, o resultado será 0. Ou seja, 1 e 1 = 1 , enquanto 1 e 0 = 0 .


A rigor, existe um quarto número binário de 3 bits para os bits setuid, setgid e sticky. É por isso que você costuma ver permissões e máscaras especificadas com um 0 inicial (ou algum outro número inicial de 0 a 7). por exemplo, 0777 ou 2755.

cas
fonte
2
Bem, tecnicamente, é octal, não decimal, mas isso realmente não muda o núcleo da resposta.
David Z
@ DavidD: O OP achou que era decimal (veja o exemplo de subtração no Q), que é presumivelmente o que cas estava se referindo.
Corridas do Lightness em órbita
1
@ Lightness, os exemplos de subtração fornecidos pelo OP funcionam octal ou decimal, dado que nenhum dígito atinge 8 e nunca é necessário transportar. Concordo que é possível que o OP estivesse pensando em decimal, mas nada na pergunta prova isso.
Stephen Kitt
@StephenKitt: Parece que meu dedo deve ter escorregado no teclado quando eu estava escrevendo exemplos em calc.exe para provar isso 😂
Leveza raças em órbita
1
@cas sim, eu não estava discordando dessa parte (é a base da minha resposta também), apenas com a afirmação de Lightness de que o OP estava calculando em decimal em vez de em octal.
Stephen Kitt