Script cambio de permisos

hipNo-

Buenas! Tengo un ejercicio que se supone es simple, pero no me llega a funcionar del todo

Lo que se pide es: Crear un script que pida el nombre de un ARCHIVO y le cambie los permisos al tipo de usuario GRUPO por los permisos contrarios

Me explico, si el fichero prueba.txt tiene permisos rw- y una vez aplicado el script debe pasar a --x

Lo que tengo hasta ahora es esto:

#!/bin/bash
#FUNCIONES#
pintarpuntos(){
contador=0
	until [ $contador = 4 ]; do
		sleep 0.5
		echo -n "."
		contador=$(($contador+1))
	done
}

mostrarpermisostotales(){
echo "Los permisos de tu archivo/carpeta son: "
permisos=$(ls -al |grep $objeto)
echo $permisos
}


mostrarpermisos(){
echo "Los permisos de grupo de tu archivo o carpeta son: "
permisos=$(ls -al|grep $objeto|cut -c 5-7)
echo $permisos
}


mostrarpermisoscambiados(){
echo "LOS NUEVOS PERMISOS DE GRUPO DE TU ARCHIVO/DIRECTORIO SON: "
permisos=$(ls -al|grep $objeto|cut -c 5-7)
echo $permisos
}


cambiarpermisos(){
echo "Vamos a invertir los permisos de grupo de tu archivo/carpeta seleccionado"

permisoL=$(ls -al|grep $objeto|cut -c 5)
permisoE=$(ls -al|grep $objeto|cut -c 6)
permisoX=$(ls -al|grep $objeto|cut -c 7)


if [ $permisoL = r ];
then
	chmod g-r $objeto
else
	chmod g+r $objeto
fi
w='w'

if [ $permisoE = $w ];
then
	chmod g-w $objeto
else
	chmod g+'w' $objeto
fi

if [ $permisoX = x ];
then
	chmod g-x $objeto
else	
	chmod g+x $objeto
fi

}

#FIN FUNCIONES#

echo "Escribe el nombre del archivo o directorio"
read objeto
bandera=0
if [ -z "$objeto" ]; then
	
echo "No existe"
fi


if [ -d $objeto ];then
	clear
	mostrarpermisos
	cambiarpermisos
	mostrarpermisoscambiados
	
fi

if [ -f $objeto ];then
	clear
	mostrarpermisos
	cambiarpermisos
	mostrarpermisoscambiados
			
fi
C

Aquí doy una solución ayudándome de Perl, y haciendo operación de bits para cambiar los permisos en octal. Si no puedes usarlo al menos puede servirte como pista para resolverlo en bash:

ls -l inputfile | 
      perl -MList::Util=sum -anE '
        $F[0] = reverse split q| |, substr $F[0], 1; 
        while ($F[0] =~ m/\G(.)/g) { 
            unshift @p, $1 eq q|-| ? 0 : 1 << (pos($F[0]) - 1) % 3; }; 
            while (@p) { 
                push @perms, sum splice @p, 0, 3 
            }
            $perms[1] = 7 - $perms[1]; 
            chmod oct(join(q||, @perms)), "inputfile"
'

¿Cómo funciona?

El array @F tiene cada campo de la línea una vez separada con espacios. $F[0] es el primer campo, que contiene los permisos.

$F[0] = reverse split q| |, substr $F[0], 1;

quita el primer caracter de los permisos que indica el tipo de fichero, no es necesario y sólo molesta. También le doy la vuelta, que se entiende más tarde.

while ($F[0] =~ m/\G(.)/g) {
...
}

Recorre los permisos caracter a caracter.

unshift @p, $1 eq q|-| ? 0 : 1 << (pos($F[0]) - 1) % 3; };

Introduce en el array @p el valor de cada permiso según su posición. pos() indica la posición del caracter en la expresión regular. Si el caracter es '-', da igual, tiene valor 0. Si no, hago operación de bits.

Ejemplo, el original: -rw-r-xr--

tras quitar el primer caracter queda rw-r-xr--, tras darle la vuelta queda: --rx-r-wr, y el bucle while empieza por '-' e introduce un 0 en el array, coge el '-', otro 0, coge el 'r', pos() devuelve 2, (3-1)%3 = 2, y correr un 1 dos posiciones queda en 4. por lo que para el original r--, en el array se han guardado 004, más o menos encaja. Y así con el resto.

Al final en el array quedan 4 2 0 4 0 1 4 0 0, al revés porque uso unshift (añadir por el principio) en lugar de push. Así revierto el reverse del principio.

        while (@p) { 
            push @perms, sum splice @p, 0, 3 
        }

coge las posiciones de 3 en 3 y las suma, con lo que quedaria:

654

        $perms[1] = 7 - $perms[1]; 
        chmod oct(join(q||, @perms)), "inputfile"

Resto de 7 (rwx en octal) los permisos de grupo, quedando 624, y los cambio usando chmod.

Resultado:

-rw--w-r--

Quizás exista algún comando para hacer este trabajo de una manera más corta y precisa, pero yo lo desconozco.

gAdrev

Python 2.x:

# flipgmod.py
import os
import sys

path = sys.argv[1]
if not os.path.exists(path):
    print "Error - no existe el archivo: " + path
    sys.exit(1)

# Permisos actuales
s = os.stat(path).st_mode
# Invertir los permisos de grupo
os.chmod(path, (~s & 0o070 ) | (s & 0o707) )

Usuarios habituales