ALGUNAS IDEAS Y EJEMPLOS

 

En esta sección voy añadiendo cosas que me van pareciendo interesantes, a nivel general, basándome en las actividades habituales. Tened en cuenta que las escribo casí de memoria, por lo que no sería extraño que hubiera algún error. En tal caso me gustaría que me lo comentarais para subsanarlo. Si conoceis alguna utilidad y quereis exponerla decídmelo.

Esta sección es un complemento a la sección Shell Scripts.


¿Como emular el DOSKEY en UNIX (Esc-K)?

En el archivo $HOME/.profile deberá exitir, si no existe habrá que añadir en un punto por el que siempre se pase -generalmente el principio- lo siguiente:

  HISTFILE=$HOME/.history
  HISTSIZE=64
  EDITOR=/usr/bin/vi # el PATH correcto donde se encuentre ubicado el comando vi
  export HISTFILE HISTSIZE EDITOR

Antes de usar $HOME, por supuesto que debe estar definido. El tamaño 64 es recomendado, puedes poner el que quieras. El nombre del archivo en principio puede ser cualquiera, pero eligelo con lógica.

Si trabajas bajo una plataforma con entorno gráficos, es posible que no fucione, para ello deberás localizar el .profile equivalente, o habilitar algún parámetro definido en dicho profile, que permita correr el .profile. Bajo la plataforma HP-UX, en el archivo .dtprofile, bajo tu directorio, hay que activar el parámetro DTSOURCEPROFILE=TRUE (quitale el comentario (#)). Por supuesto debes reiniciar la sesión en cualquiera de los casos.

También se puede conseguir mediante el comando:

 $ set -o vi

 

Una Papelera de Reciclaje. No borres tus archivos de forma definitiva. Recuperalos!!!

( ¡ No es aplicable a root por motivos de seguridad en sistemas multiusuario ! )

Crea un directorio (en tu directorio de usuario) con un nombre cualquiera, pero significativo (p.e. trash). En tu $HOME o en el directorio en que tengas tus ejecutables, create un archivo llamado rm, e inserta en él:

/bin/mv $* $HOME/trash	# /bin se debe sustituir por la ubicación real de mv

Deberá tener permiso, al menos, de ejecución y lectura para el propietario:

chmod 700 rm

En tu archivo .profile deberás cambiar PATH=..., de modo que aparezca antes el directorio que contiene el nuevo rm que el directorio que contiene el rm real (/bin o /usr/bin, depende del sistema), con el fin de que sea localizado antes el nuevo rm que el original.
Con esto lo que se consigue es mover los archivos que se quieren borrar a un subdirectorio, por si interesara recuperarlos. Deberás limpiar este directorio de forma periódica, para lo cual te puedes generar un archivo en el mismo directorio que el anterior que contenga una instrucción como:

/bin/rm $HOME/trash/*

o en el .profile:

find $HOME/trash -atime [DIAS] -exec /bin/rm {} \;

 

Backgrounds activos

Si ejecutas un shell script que tarda algún tiempo, lo suficiente como para mosquear al usuario, y quieres que el usuario se crea que todo va bien, prueba a incluir lo siguiente en tu shell script (puedes cambiar el punto que se imprime por cualquier carácter o símbolo, pero cuidado con las secuencias de escape):

function puntos ()
	{
	if [ $1 ]
		then
			tiempo = $1 	# Lo que le indiques
		else
			tiempo = 5 	# 5 segundos por defecto
	fi
	while true
		do
			echo ".\c"
			sleep $tiempo
		done
	}

Programa principal:

puntos 1 &	# Cada segundo imprimirá un punto
PROGRAMA		# programa a ejecutar
kill -9 $!	# Finaliza el último programa lanzado en background presenta los resultados como quieras
if [ -f $out ]	# Si se generó el archivo de salida. Prueba a insertar otras funciones
	then
		echo "Los resultados estan en $SALIDA"
	else
		echo "Algo ha fallado"
fi

 

¿Aliases o Funciones?

Habitualmente los aliases se guardan en un archivo cuyo nombre suele ser .aliases, o .env, se puede comprobar visualizando la variable de entorno $ENV. En otras ocasiones puede estar almacenado en el propio .profile. Los aliases vienen a tener la siguiente estructura:

alias ll="ls -l"			o 		alias ll=´ls -l´
alias fcore="find / -name core -print -exec rm{} \;"

pero podemos comprobar que no admiten variables como argumentos. Para solucionar esta carencia lo que podemos usar son funciones, teniendo en cuenta que $1, $2, etc. Son los argumentos que se pasan a la función. Evidentemente, al tratarse de funciones, las podemos construir tan complejas como deseemos, pudiendo llegar a ser auténticos programas.
Como ejemplo veamos la siguiente función que busca una cadena de caracteres en todos los archivos que cuelgan de un subdirectorio determinado, y en los subdirectorios que a su vez cuelgan de él, es decir, en el árbol descendente del subdirectorio que elijamos.

function Ffind ()
	{
	if [ $2 ]		# Se comprueba si existe 1 o 2 argumentos
		then
			DIR_INICIAL=$1
			CADENA=$2
		else
			if [ $1 ]
				DIR_INICIAL=.
				CADENA=$1
			else
				echo "Sintaxix: Ffind <directorio> <cadena>"
				return 0
			fi
	fi
	# Ahora obtenemos el árbol de directorios sobre el que hay que buscar
	DIRECTORIOS=´find $DIR_INICIAL -depth -type d -print´	
	for i in $DIRECTORIOS
		do
			echo "Buscando $CADENA en $i"
			grep $CADENA $i/*       # Puedes usar las opciones que quieras del comando grep
		done
	}

Esta función estaría en el archivo de aliases y sería de uso exclusivo del propietario, invisible a los demás.
La puedes mejorar con más opciones, emplear recursividad, etc., el caso es que debe ser útil y lo más rápida posible, para lo cual debe consumir el mínimo de recursos. La sintaxis que se emplearía, en el caso expuesto, sería:

Ffind <directorio> <cadena>

Un ejemplo de alias dinámico, que cambie el directorio de acceso en función del año en que nos encontremos puede ser del tipo:

alias cdano="ANO=`date +%Y` ; cd /home/user/$ANO

El resto es cuestión de imaginación.


 

Borrar archivos que contienen metacaracteres en su nombre.

En ocasiones se generan archivos, por error o no, que continen caracteres extraños o metacaracteres como ?, *,^C ,^H, etc. y que no pueden ser borrados habitualmente con el comando rm. Para eliminar estos archivos se puede emplear el siguiente método:

  1. Listar el directorio en el que se encuentre con el comando ls -li, con el fin de anotar el i-nodo que le corresponde.
    ls -li [directorio]
  2. Buscar en ese directorio el archivo con el número de i-nodo que le corresponde y borrarlo:
    find [directorio] -inum [i-nodo] -ok -exec rm {} \;

La opción -ok se incluye para que pida confirmación.


 

Ejecución de comandos en otra máquina sin tener que acceder explícitamente.

Para ello puedes realizar un rsh (remote shell, no restricted shell) o remsh indicando el nombre de la máquina, pero si generas un archivo con el nombre de la máquina en tu directorio de ejecutables, y lo linkas al rsh o remsh podras realizar la misma operación tecleando simplemente el nombre de la máquina y el comando a ejecutar. Esto viene documentado, solo tienes que hacer un man rsh (o remsh, dependiendo del UNIX que tengas cargado) y leer por el medio.

Por supuesto debes tener tener cuenta en dicha máquina y el acceso habilitado mediante el archivo .rhosts bajo tu directorio.


 

Visualizar los procesos ejecutados por todos los usuarios conectados al sistema (whodo).

Este script, que simula el comando whodo, permite visualizar los programas que tiene cada usuario en ejecución, así como su dirección IP, tiempo de inactividad, terminales asociados, etc.

#!/usr/bin/ksh

usuarios=`who -u`
usu=`echo "$usuarios" | cut -f1 -d " " | sort -u`
for i in $usu
	do
		echo "$usuarios" |grep $i
		ps -x -u $i
	done


 

Ejecución remota de comandos mediante ssh sin necesidad de validación.

En ocasiones puede ser necesario automatizar la ejecución de tareas en sistemas remotos sin necesidad de introducir la clave de acceso. Para conseguirlo hay que realizar el procedimiento que se detalla a continuación.

El procedimiento consta de dos partes, la primera solo ha de realizarse una única vez en el sistema origen, mientras que la segunda ha de realizarse una vez por cada sistema en el que se quieran ejecutar comandos de forma remota mediante el comando ssh. Si por algún motivo se vuelve a ejecutar la primera parte después de habar ejecutado la segunda en algún sistema remoto, habrá que repetir la segunda parte en todos los sistemasm, pues la clave generada en la primera parte será diferente en cada caso.

  1. Procedimiento inicial.

    Se realiza solo una vez en el sistema desde el que se lanzarán los comandos y consiste en generar la clave rsa publica/privada, que se almacenará en el archivo $HOME/.ssh/id_rsa (siendo $HOME el directorio del usuario para el que se genera la clave). A las preguntas que va haciendo se responde pulsando la tecla <Return> para aceptar los valores por defecto. La identificación se guardará en el archivo $HOME/.ssh/id_rsa mientras que la clave pública lo hará en $HOME/.ssh/id_rsa.pub, que es la que en el segundo procedimiento exportaremos a los sistemas remotos.

    $ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Please be patient....   Key generation may take a few minutes
    Enter file in which to save the key ($HOME/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in $HOME/.ssh/id_rsa.
    Your public key has been saved in $HOME/.ssh/id_rsa.pub.
    The key fingerprint is:
    bf:7a:4e:66:a6:b9:3f:ce:9e:9a:fa:46:a7:d8:44:c2 usuario@sistema
    The key's randomart image is:
    +--[ RSA 2048]----+
    |                 |
    |                 |
    |     . .         |
    |      E .        |
    |      ooS        |
    |        o..      |
    |       = o*      |
    |      . +Xoo     |
    |      .+OXO.     |
    +-----------------+
    
  2. Procedimiento en los sistemas remotos.

    Esta parte hay que ejecutarla en todos y cada uno de los sistemas en los que queramos ejecutar tareas sin tener que validarnos. El procedimiento consiste en copiar la clave pública, generada en el primer procedimiento en el sistema origen, en todos los sistemas remotos. Crearemos el directorio remoto usuario/.ssh por si no existiera y después añadimos la clave antes generada al archivo usuario/.ssh/authorized_keys

    $ ssh -l usuario sistema mkdir -p .ssh
    usuario@sistema's password:
    
    $ cat $HOME/.ssh/id_rsa.pub | ssh -l usuario sistema 'cat >> .ssh/authorized_keys'
    usuario@sistema's password:
    
    $ ssh -l usuario sistema uname -a
    SunOS sistema 5.8 Generic_108528 sun4u sparc SUNW,Sun-Fire-280R
    

    También se podría haber utilizado la forma usuario@sistema para la conexión en lugar de la opción -l usuario sistema.

Conviene hacer 2 comprobaciones de permisos para evitar fallos (como que nos pida la clave de acceso) después de haber completado los procedimientos, y son:

En caso de tener que cambiar alguno de los permisos utilizar el comando chmod.