¿Cómo puedo obtener permisos de archivo octal desde la línea de comandos?

373

Hay un comando chmod para establecer permisos de archivo, pero ¿puedo obtener permisos de archivo en modo octal (como 755) desde la línea de comandos?

Anwar
fuente
2
Para personas como yo que accidentalmente aterrizaron en esta página pero en realidad estaban buscando cómo hacer esto en Mac: stackoverflow.com/a/14855227/470749
Ryan
2
stat --format "%A" $FILEte da el drwxr-x---formato legible por humanos . que puede o no ser útil.
Trevor Boyd Smith

Respuestas:

535

Puedes probar

stat -c "%a %n" *

Reemplace *con el directorio relevante o el nombre de archivo exacto que desea examinar.

Desde la página de manual 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

Uso:

  • Con archivos:

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

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

(Referencia)

jokerdino
fuente
57
en mac os, use stat -f '%A %a %N' *(crédito: geeklog.adamwilson.info/article/58/… )
s2t2
1
Si está más cómodo con ls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends
2
@usandfriends en bucle en la salida de lses una mala idea. Si realmente quieres usar un bucle, puedes hacerlofor f in *; do stat "%a %n" "$f"; done
Tom Fenech
1
¿Por qué en Mac OS todo cambia ligeramente (incluso en las utilidades iso de Unix)? ¿Hay alguna razón real de esto?
Vassilis
2
@Hackel, cuéntanos cómo te sientes realmente. jajaja
MikeSchinkel
44

Los permisos de archivo en Linux se pueden mostrar en formato octal utilizando el comando stat de Linux.

Simplemente presione Ctrl+ Alt+ Ten su teclado para abrir Terminal. Cuando se abra, navegue al directorio donde desea encontrar los permisos de archivo en modo octal.

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

% A Derechos de acceso en forma legible para humanos

% a Derechos de acceso en octal

% n Nombre de archivo

Números octales y permisos

Puede usar el número octal para representar el modo / permiso:

r: 4
w: 2
x: 1

Por ejemplo, para el propietario del archivo, puede usar el modo octal de la siguiente manera. El permiso de lectura, escritura y ejecución (completo) en un archivo en octal es 0 + r + w + x = 0 + 4 + 2 + 1 = 7

Solo el permiso de lectura y escritura en un archivo en octal es 0 + r + w + x = 0 + 4 + 2 + 0 = 6

Solo leer y ejecutar permisos en un archivo en octal es 0 + r + w + x = 0 + 4 + 0 + 1 = 5

Use el método anterior para calcular el permiso para el grupo y otros. Digamos que desea otorgar permiso completo al propietario, leer y ejecutar permiso para agrupar y leer solo permiso para otros, luego debe calcular el permiso de la siguiente manera: Usuario = r + w + x = 0 + 4 + 2 + 1 = 7 Grupo = r + w + x = 0 + 4 + 2 + 0 = 6 Otros = r + w + x = 0 + 0 + 0 + 1 = 1

El permiso efectivo es 761.

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

Mitch
fuente
2
El 0 inicial también representa un bit especial: pastebin.com/6ymkFt71
Braiam
36

Como se detalla en los permisos de estilo "755" con 'ls' de Adam Courtemanche en AgileAdam.com , puede crear un alias lso que actúe ls -lpero procese ligeramente la salida 1 para mostrar los permisos también en octal. Esto agrega una columna inicial que muestra los permisos octales de dos dígitos de tres dígitos . Como está escrito, esto funciona para la mayoría de los archivos y directorios, pero no funciona correctamente si los pegajosos o setuid / setgid se establecen bits. 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}'"

Sin embargo, esto tiene una grave deficiencia, como señala techtonik . No puede pasar argumentos a este alias como lo haría con el comando , porque en su lugar se toman como argumentos adicionales . Por lo tanto, no puede ejecutarse en un archivo o directorio específico, ni puede pasar ninguna opción (como o ) .lsolsawklso-F--colorlso


La solución es definir lso como una función en lugar de 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 está probando esto de forma interactiva en su shell, ejecute unalias lsopara eliminar el alias; puede hacerlo antes o después de definir la función. Si lo está colocando en un archivo de origen, por ejemplo ~/.bashrc, simplemente saque la aliaslínea y agregue la definición de la función.

¿Por qué funciona esto? A diferencia de los alias, las funciones de shell bash pueden tomar parámetros posicionales , es decir, argumentos de línea de comandos . "$@"se expande a la lista de argumentos completa , haciendo lsoque se pasen argumentos a la función ls. (A diferencia de una definición de alias, no se cita un cuerpo de función; por lo tanto, era necesario eliminar los \caracteres antes $y ").

Dado que puede pasar opciones a lsocuando se define de esta manera como una función, es posible que desee eliminar las opciones -ay -Gde la definición; puede pasarlas manualmente en los casos en que las desee. ( El -lse requiere opción para detalles como los permisos de archivo que se muestra en absoluto , por lo que no hay ningún beneficio a retirarlo.)

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

Gracias a techtonik por señalar la limitación en la definición lsocomo un alias, lo que me motivó a expandir esta publicación con material sobre cómo convertirla en una función.


1 Uno puede notar que esto parece ignorar la regla general sobre no analizar la salida dels . lsproduce una salida muy legible para el ser humano; Esto introduce idiosincrasias y limitaciones, por lo que generalmente no es adecuado como entrada para otros comandos. En este caso analizamos lsya que deseamos preservar el comportamiento exacto dels excepto nuestro único cambio agregado.

2 Una limitación de este alias, que también se aplica a la versión de la función que se muestra debajo, y que puede considerarse un error, es que solo muestra tres dígitos octales incluso cuando el cuarto dígito octal es cero. Como jfmercer ha señalado correctamente , los dígitos octales que se muestran aquí no reflejan el bit adhesivo si está presente, ni los bits setuid o setgid.

3 Más serio que simplemente no mostrar el cuarto dígito octal es que este método asume que no se han establecido, y si son - si usted ve t, so Sen la serie de permiso - entonces usted debe ignorar los dígitos octales . Esto se debe a que los bits se infieren de la cadena de permisos de una manera que no tiene en cuenta los bits fijos setuid / setgid.

Eliah Kagan
fuente
no funciona con directoriosawk: read error (Is a directory)
anatoly techtonik
@techtonik ¡Gracias por señalar esto! (Finalmente) actualicé esta respuesta para incluir una solución para eso.
Eliah Kagan
1
Puede agregar --colorparámetros para mostrar coloreslso() { 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
¿Has descubierto una solución al problema setuid / setgid desde que publicaste esto?
Silvestris
21

Simplemente extendiendo \ simplificando respuestas relacionadas con 'estadísticas' anteriores:

Simplemente puede ejecutar:

stat <path_to_file>

La salida contendrá permiso octal junto con otra información.



Detalles (versión estadística y ejemplo):

# 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

Tenga en cuenta lo siguiente: ( 0644 / -rw-r - r--)

Vano
fuente
6

Para la portabilidad, puede 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

Si desea notar cuándo ocurre un error, intente:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt
Cuonglm
fuente
2
Además de ser portátil, la solución de @ cuonglm muestra cuatro caracteres octales en lugar de tres , mostrando así el estado del "bit adhesivo" que a menudo se olvida.
jfmercer
2

Puedes usar findcon la -printfacción.

lsno muestra permisos octales, pero puede usar esta findsolución alternativa basada en:

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

Por ejemplo, para consultar mi directorio de Videos:

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

El %mespecificador de formato le dice a la -printfacción que imprima permisos octales, mientras que el %fespecificador de formato hace que imprima el nombre del archivo.

Puede pasar varios nombres de archivo a find. Incluso puedes usar globos (por ejemplo, find * -printf "%m:%f\n").

No tiene que usar una prueba como -nameo -iname; es suficiente pasar los nombres de los archivos o directorios que le interesan como puntos de partida find. Es decir, proporcione sus nombres como argumentos inmediatamente después de la palabra find, como se muestra arriba.

findle da un gran control sobre cómo muestra la salida. Hay dos modificaciones en particular que pueden resultarle útiles:

  • Por defecto, findrecurre subdirectorios, similares a ls -R. Si no desea findvisitar los subdirectorios de los puntos de partida que le pasa, puede agregar -maxdepth 0(o usar -maxdepthcon otros valores para indicar qué tan profundo quiere que vaya).

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %fsolo muestra un nombre de archivo, por lo que si findtiene que recurrir para acceder a un archivo, es posible que no sepa dónde está ubicado. Para mostrar una ruta, comenzando por el punto de inicio en el que se encontró el archivo, use %pen su lugar.

    $ 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 obtener más información sobre el uso del findcomando.

Otro método ( lsy awk)

Esto se puede usar para enumerar todos los archivos de directorio con sus permisos:

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 es esencialmente el mismo comando que en el lsoalias de Adam Courtemanche , que esa respuesta citó, solo se ejecuta como un solo comando. Si solo usa esto una vez, o en raras ocasiones, es posible que no quiera molestarse en escribirlo como un alias o función de shell.

Maythux
fuente