Como posso obter permissões de arquivo octal na linha de comando?


373

Existe um comando chmod para definir permissões de arquivo, mas posso obter permissões de arquivo no modo octal (como 755) na linha de comando?


2
Para pessoas como eu, que chegaram acidentalmente a esta página, mas na verdade estavam procurando como fazer isso no Mac: stackoverflow.com/a/14855227/470749
Ryan

2
stat --format "%A" $FILEfornece o drwxr-x---formato legível por humanos . o que pode ou não ser útil.
Trevor Boyd Smith

Respostas:


535

Podes tentar

stat -c "%a %n" *

Substitua *pelo diretório relevante ou pelo nome de arquivo exato que você deseja examinar.

Na página de manual do 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

Uso:

  • Com arquivos:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
    
  • Com pastas:

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

(Referência)


57
no mac os, use stat -f '%A %a %N' *(credit: geeklog.adamwilson.info/article/58/… )
s2t2

1
Se você está mais à vontade com ls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends

2
@usandfriends dar laços na saída de lsé uma má ideia. Se você realmente quiser usar um loop que você pode fazerfor f in *; do stat "%a %n" "$f"; done
Tom Fenech

1
Por que no Mac OS tudo mudou um pouco (mesmo no unix iso utils)? Existe uma razão real disso?
Vassilis

2
Por favor, @hackel, conte-nos como você realmente se sente. ri muito!
MikeSchinkel #

44

As permissões de arquivo no Linux podem ser exibidas no formato octal usando o comando stat do Linux.

Basta pressionar Ctrl+ Alt+ Tno teclado para abrir o Terminal. Quando abrir, navegue até o diretório em que deseja encontrar as permissões de arquivo no modo octal.

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

% A Direitos de acesso em formato legível por humanos

% a Direitos de acesso em octal

% n nome do arquivo

Números e permissões octais

Você pode usar o número octal para representar o modo / permissão:

r: 4
w: 2
x: 1

Por exemplo, para o proprietário do arquivo, você pode usar o modo octal da seguinte maneira. A permissão de leitura, gravação e execução (completa) em um arquivo em octal é 0 + r + w + x = 0 + 4 + 2 + 1 = 7

Somente a permissão de leitura e gravação em um arquivo octal é 0 + r + w + x = 0 + 4 + 2 + 0 = 6

Somente a permissão de leitura e execução em um arquivo octal é 0 + r + w + x = 0 + 4 + 0 + 1 = 5

Use o método acima para calcular a permissão para grupos e outros. Digamos que você queira conceder permissão total ao proprietário, ler e executar permissão para agrupar e ler somente permissão para outras pessoas, então você precisa calcular a permissão da seguinte maneira: Usuário = r + w + x = 0 + 4 + 2 + 1 = 7 Grupo = r + w + x = 0 + 4 + 2 + 0 = 6 Outros = r + w + x = 0 + 0 + 0 + 1 = 1

A permissão efetiva é 761.

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


2
A inicial 0 representam pouco especial também: pastebin.com/6ymkFt71
Braiam

36

Conforme detalhado nas permissões no estilo “755” com 'ls' de Adam Courtemanche no AgileAdam.com , você pode criar um alias lso que age como, ls -lmas processa levemente a saída 1 para exibir permissões também em octal. Isso adiciona uma coluna à esquerda mostrando três dígitos 2 permissões octais. Como escrito, isso funciona para a maioria dos arquivos e diretórios, mas ele não funciona corretamente se as pegajosas ou setuid / setgid bits são definidos. 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}'"

Isso tem uma falha séria, como o techtonik aponta . Você não pode passar argumentos para esse lsoalias como faria com o lscomando , porque eles são tomados como argumentos adicionais awk. Portanto, você não pode executar lsoem um arquivo ou diretório específico, nem pode passar opções (como -Fou --color) para lso.


A correção é definir lso como uma função e não como um 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}'; }

Se você estiver tentando fazer isso de forma interativa no seu shell, execute unalias lsopara remover o alias - você pode fazer isso antes ou depois de definir a função. Se você estiver colocando-o em um arquivo de origem, como ~/.bashrc, basta retirar a aliaslinha e adicionar a definição da função.

Por que isso funciona? Diferentemente dos pseudônimos, as funções do shell bash podem aceitar parâmetros posicionais , como argumentos da linha de comando . "$@"expande para a lista completa de argumentos , fazendo com que os argumentos para a lsofunção sejam passados ​​para ls. (Diferentemente de uma definição de alias, um corpo de função não é citado; portanto, foi necessário remover os \caracteres antes $e ".)

Como você pode passar opções para lsoquando definidas dessa maneira como uma função, convém remover as opções -ae -Gda definição - você pode passá-las manualmente nos casos em que desejar. ( A -lopção é necessária para detalhes como as permissões de arquivo para ser mostrado em tudo , então não há nenhum benefício para removê-lo.)

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}'; }

Agradeço ao techtonik por apontar a limitação na definição de lsoum alias, motivando-me a expandir este post com material sobre como torná-lo uma função.


1 Pode-se notar que isso parece desrespeitar a regra geral de não analisar a saídals . lsproduz saída muito legível por humanos; isso introduz idiossincrasias e limitações, tornando-o geralmente inadequado como entrada para outros comandos. Neste caso, nós analisamos lsuma vez queremos preservar o comportamento exato dels exceto nosso uma mudança acrescentou.

2 Uma limitação desse alias, que também se aplica à versão da função mostrada abaixo, e que pode ser considerada um bug, é que ele exibe apenas três dígitos octais, mesmo quando o quarto dígito octal é zero. Como jfmercer tem justamente salientou , os dígitos octais exibidos aqui não refletem a pouco pegajoso se os bits presentes, nem setuid ou setgid.

3 Mais sério do que meramente não mostrando o quarto dígito octal é que este método assume que eles não estão definidos, e se eles são - se você ver t, sou Sna cadeia de permissão - então você deve ignorar os dígitos octais . Isso ocorre porque os bits são deduzidos da cadeia de permissões de uma maneira que não considera os bits fixos / setgid.


não funciona com diretórios -awk: read error (Is a directory)
anatoly techtonik

@techtonik Obrigado por apontar isso! (Finalmente) atualizei esta resposta para incluir uma correção para isso.
Elias Kagan

1
Você pode adicionar --colorparâmetro para mostre coreslso() { 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
você descobriu uma solução para o problema persistente de setuid / setgid desde que publicou isso?
Silvestris

21

Apenas estendendo \ simplificando as respostas anteriores relacionadas ao 'stat':

Você pode simplesmente executar:

stat <path_to_file>

A saída conterá permissão octal junto com outras informações.



Detalhes (versão estatística e exemplo):

# 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

Observe o: ( 0644 / -rw-r - r--)


6

Para portabilidade, você pode usar 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

Se você deseja perceber quando ocorre um erro, tente:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt

2
Além de portátil, a solução do @ cuonglm mostra quatro caracteres octais em vez de três , mostrando assim o estado do "pedaço pegajoso" que é frequentemente esquecido.
Jfmercer

2

Você pode usar findcom a -printfação.

lsnão mostra permissões octais, mas você pode usar esta findsolução alternativa:

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

Por exemplo, para verificar meu diretório de vídeos:

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

O %mespecificador de formato informa à -printfação para imprimir permissões octais, enquanto o %fespecificador de formato faz com que imprima o nome do arquivo.

Você pode passar vários nomes de arquivos para find. Você pode até usar globs (por exemplo, find * -printf "%m:%f\n").

Você não precisa usar um teste como -nameou -iname; é suficiente passar os nomes dos arquivos ou diretórios nos quais você está interessado como pontos de partida find. Ou seja, forneça seus nomes como argumentos imediatamente após a palavra find, como mostrado acima.

findfornece um ótimo controle sobre como mostra a saída. Há duas modificações em particular que você pode achar úteis:

  • Por padrão, findrecursa subdiretórios, semelhantes a ls -R. Se você não quiser findvisitar os subdiretórios dos pontos de partida que você passa para ele, é possível adicionar -maxdepth 0(ou usar -maxdepthcom outros valores para indicar a profundidade que você deseja).

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %fmostra apenas um nome de arquivo; portanto, se findfor necessário recursar para acessar um arquivo, talvez você não saiba onde ele está localizado. Para mostrar um caminho, começando com o ponto inicial em que o arquivo foi encontrado, use-o %p.

    $ 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
    ....

Consulte man findpara obter mais informações sobre como usar o findcomando

Outro método ( lse awk)

Isso pode ser usado para listar todos os arquivos de diretório com suas permissões:

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}'

Este é essencialmente o mesmo comando que no pseudônimo de Adam Courtemanchelso , que essa resposta citou, apenas roda como um único comando. Se você estiver usando isso apenas uma vez, ou em raras ocasiões, talvez não queira se incomodar em escrevê-lo como um alias ou função de shell.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.