Cómo inspeccionar los permisos de grupo de un archivo

9

Me gustaría inspeccionar los permisos de grupo de un archivo desde un script bash. Específicamente, necesito verificar si un archivo tiene el bit de escritura del grupo.

Eso es. Simple como eso. Sin embargo:

  1. También necesito que esto sea portátil.
  2. test -w <file no me dirá si se puede escribir en grupo.
  3. El resultado de ls -ldes bueno para los humanos, pero no estoy tan seguro de los scripts. Técnicamente podría analizar resultados como drwxrwxr-xextraer los bits del grupo, pero esto parece frágil.
  4. La interfaz para states completamente incompatible entre OS X y otros sistemas.
  5. find <file> -perm ... no puede ser la respuesta?
mislav
fuente
¿Necesita verificar el bit de permiso de grupo, o necesita verificar si un grupo específico tiene permisos de escritura? El grupo (o el usuario) podría tener permiso de escritura a través de una ACL.
Gilles 'SO- deja de ser malvado'
Solo el bit de permiso de grupo. Ningún grupo específico es relevante.
mislav

Respuestas:

8

Método # 1 - stat

Puede usar el statcomando para obtener los bits de permisos. statestá disponible en la mayoría de Unixes (OSX, BSD, no AIX de lo que puedo encontrar). Esto debería funcionar en la mayoría de los Unix, excepto OSX y BSD de lo que puedo encontrar.

$ stat -c "%a" <file>

Ejemplo

$ ls -l a
-rw-rw-r-- 1 saml saml 155 Oct  6 14:16 afile.txt

Usa este comando:

$ stat -c "%a" afile.txt
664

Y use un modo simple greppara ver si el modo de permisos de grupos es un 6 o 7.

$ stat -c "%a" afile.txt | grep ".[67]."

Para OSX y BSD que había necesidad de utilizar esta forma de stat, stat -f(o tal vez stat -x), y analizar en consecuencia. Dado que las opciones statson diferentes, puede incluir este comando en un lsb_release -acomando y llamar a la versión adecuada según el sistema operativo. No es ideal pero viable. Tenga en cuenta que sololsb_release está disponible para distribuciones de Linux, por lo que sería necesario idear otra alternativa para probar otros sistemas operativos Unix.

Método # 2 - encontrar

Sin embargo, creo que este comando podría servirle mejor. Hace uso de findy el printfinterruptor.

Ejemplo

$ find a -prune -printf '%m\n'
664

Método # 3 - Perl

Perl podría ser una forma más portátil de hacer esto dependiendo de los sistemas operativos que intente cubrir.

$ perl -le '@pv=stat("afile.txt"); printf "%04o", $pv[2] & 07777;'
0664

NOTA: Lo anterior hace uso de la stat()función de Perl para consultar los bits del sistema de archivos.

Puede hacerlo más compacto si deja de utilizar una matriz @pvy trata stat()directamente con la salida de :

$ perl -le 'printf "%04o", (stat("a"))[2] & 07777;'
0664
slm
fuente
Creo que te perdiste su punto 4. El statcomando varía ampliamente entre los diferentes sistemas y no es portátil.
jordanm
@jordanm: gracias. Lo vi. Estaba buscando una alternativa. Creo que find . -printfpuedo hacerlo pero no puedo determinar si está disponible en OSX 'find.
slm
1
Tampoco pude encontrarlo en la guía POSIX2008, así que estoy de acuerdo. No estoy seguro de ningún otro método. Creo que tienes que morder la bala aquí y detectar qué sistema operativo y llamar al aprop. comando, parece ser el mejor enfoque.
slm
1
Tampoco podía pensar en un método que utilizara una utilidad de shell estándar. Es por eso que mi respuesta usa perl.
jordanm
1
@jordanm - grandes mentes. Estaba trabajando en una solución perl también 8-)
slm
1

Una opción es usar perl, que será portátil en cualquier lugar perldisponible. Es difícil encontrar un sistema Unix sin él. Aquí hay un ejemplo de cómo se puede integrar en un script de shell:

if perl -e 'use Fcntl ":mode"; exit( ((stat("file.txt"))[2] & S_IWGRP) >> 3)'; then
    echo "file is group writable"
else
    echo "file is not group witeable"
fi

Se perlpueden encontrar ejemplos similares en el stat perldoc .

jordanm
fuente
1

Terminé lsanalizando:

is_group_writable() {
  local ls="$(ls -ld "$1")"
  [ "${ls:5:1}" = "w" ]
}

Estoy agradecido por la amplia respuesta de @ slm, pero ninguno de los otros métodos es tan sencillo. El statmétodo requeriría que escribiera al menos dos invocaciones diferentes para cubrir OS X, e incluso después de eso, devuelve la representación octal a la que todavía tengo que aplicar aritmética. El método Perl está bien, pero requiere que inicie un intérprete para una tarea tan simple, y me gustaría mantenerlo simple y usar solo utilidades posix.

mislav
fuente
2
Estás usando bash, no solo POSIX. En POSIX:perms=$(ls -ld -- "$1"); perms=${perms%% *}; case $perms in ?????w????) …
Gilles 'SO- deja de ser malvado'
0
FILE="filename";G=$(stat -c '%a' ${FILE} | cut -c2);
if [ $G -gt 5 ];then   echo "Group write is set on ${FILE}";fi

Todas las herramientas estándar de Unix / Linux.

Supongo que es POSIBLE tener una escritura grupal, pero no una lectura grupal. En esa posibilidad, sería una declaración de caso 2 | 3 | 6 | 7) o un grep '[2 | 3 | 6 | 7]'

Doc
fuente