¿Cuáles son las opciones, sin utilizar comandos externos, para enumerar los permisos de un archivo?
test
es una función incorporada, pero solo funcionaría para el propietario del archivo AFAIK, lo busco todo. Pensé que estaba en algo con inodes
, pero tampoco puedo encontrar una manera de leerlos (¡con funciones integradas!).
bash
solo, por favor. Cualquier versión y/o formato es aceptable.
editar:
Soy consciente de que hay innumerables formas de hacer esto usando comandos externos ( stat
,, ls
etc.), esto es solo un ejercicio de pensamiento: nada de lo que estoy haciendo "requiere" una builtin
única solución.
editar2:
La respuesta de los comandos cargables de Glenn Jackman es técnicamente correcta, ya que utiliza una función incorporada. Sin embargo, creo que esto demuestra que mi pregunta estaba mal definida.
Usando comandos puros bash
(cualquier versión) builtin
, como se enumeranaquíen el manual y otras funciones integradas bash
(redirección, sustitución, palabras clave, otras cosas que ni siquiera conozco...), en un linux
sistema, ¿cómo puedo enumerar los permisos completos que tiene un archivo? El resultado sería similar a cualquiera de los siguientes, aunque un valor de umask también funcionaría.
user@hostname$ stat test -c %A
-rw-rw-r--
user@hostname$ stat test -c %a
664
Respuesta1
Con bash simple, creo que lo mejor que puedes conseguir es algo como esto: obtienessupermisos, no de grupo u otros.
myperms() {
local file=$1
local perms=""
if [[ -d $file ]]; then
perms+='d'
elif [[ -L $file ]]; then
perms+='l'
else
perms+='-'
fi
[[ -r $file ]] && perms+='r' || perms+='-'
[[ -w $file ]] && perms+='w' || perms+='-'
[[ -x $file ]] && perms+='x' || perms+='-'
echo "$perms $file"
}
Entonces:
$ myperms /bin/bash
-r-x /bin/bash
$ touch afile
$ myperms afile
-rw- afile
$ chmod u+x afile
$ myperms afile
-rwx afile
$ ln -s afile alink
$ myperms alink
lrwx alink
$ chmod u-wx afile
$ myperms alink
lr-- alink
$ ls -l afile alink
-r--r--r-- 1 glennjackman staff 0 Dec 16 14:28 afile
lrwxr-xr-x 1 glennjackman staff 5 Dec 16 14:29 alink -> afile
Respuesta2
Con la versión 5 de bash, hay "comandos cargables": comandos que no son comandos integrados de bash, pero que se pueden habilitar para que se conviertan en comandos integrados:
- clonar el repositorio bash git:https://savannah.gnu.org/git/?group=bash
./configure --prefix=/path/where/you/want/it/installed
- hacer && hacer instalar
stat
no es un cargable "compatible", aunque existe aquí, por lo quecd ./examples/loadables
make others
cp stat /path/where/you/want/it/installed/lib/bash
Entonces
- Inicie un shell bash:
/path/where/you/want/it/installed/bin/bash
- establecer una variable de shell:
BASH_LOADABLES=/path/where/you/want/it/installed/lib/bash
- habilite el comando de estadística:
enable -f stat stat
- y usarlo:
stat -A statarray /some/file
stat
llena una matriz asociativa. Una demostración (usando la matriz predeterminada llamada "STAT")
$ ~/bash/5.0/bin/bash
$ echo $BASH_LOADABLES_PATH
/Users/glennjackman/bash/5.0/lib/bash
$ enable -f stat stat
$ stat ~/.bashrc
$ declare -p STAT
declare -A STAT=([nlink]="1" [link]="/Users/glennjackman/.bashrc" [perms]="0644" [inode]="14482796" [blksize]="4096" [device]="16777220" [atime]="1574454147" [type]="-" [blocks]="8" [uid]="502" [size]="2767" [rdev]="0" [name]="/Users/glennjackman/.bashrc" [mtime]="1574454147" [ctime]="1574454147" [gid]="20" )
$ for key in "${!STAT[@]}"; do printf "%s\t%s\n" "$key" "${STAT[$key]}"; done
nlink 1
link /Users/glennjackman/.bashrc
perms 0644
inode 14482796
blksize 4096
device 16777220
atime 1574454147
type -
blocks 8
uid 502
size 2767
rdev 0
name /Users/glennjackman/.bashrc
mtime 1574454147
ctime 1574454147
gid 20
Para configurar automáticamente la variable BASH_LOADABLE_PATH, puse mi ~/.bashrc:
# for loadable builtins
bash_root=${BASH%/bin/bash}
[[ -d "$bash_root/lib/bash" ]] && BASH_LOADABLES_PATH="$bash_root/lib/bash"
unset bash_root