4

Click here to load reader

Shell power

Embed Size (px)

Citation preview

Page 1: Shell power

El poder del shell Linux

BREVE INTRODUCCION AL SHELL (SUMARIO)Probablemente el shell en un sistema Unix o Linux, sea el primer programa con el cual un usuario interactua. La palabra "Shell" es una terminología Unix que define la interfaz de usuario mediante el cual se puede enviar instrucciones al sistema operativo o bien recibir respuestas o resultados del mismo. Se dice que el shell cumple una doble función:

Proteger al usuario de interactuar directamente con el kernel (imagínese indicando al sistema que usted quiere borrar el contenido de un directorio completo sin poder utilizar una herramienta tan simple como el metacaracter *, para hacer referencia a todos los archivos contenidos en ese directorio, y tener que espeecificar archivo por archivo...)

Proteger al kernel de errores de sintaxis mientras el usuario escribe las instrucciones, por lo que el shell decide realmente enviar aquellas órdenes que sean sintácticamente correctas al sistema operativo. A continuacion veremos algunas caracteristicas básicas, pero muy potentes del shell bash, quizas el más popular de los shells modernos de Linux.

LOS SHELLS EN LINUXUna de las caracteristicas mas fascinantes del mundo open source, es la oportunidad que poseemos como usuarios a tener (por lo general) la opción de poder elegir que programa o herramienta utilizar para realizar determinadas tareas, en el caso del shell, afortunadamente, no es la excepción. Gracias a esto, contamos con la capacidad de escoger entre por ejemplo los siguientes shells: bash, csh, ksh, zsh, tcsh, entre otros. En distribuciones modernas de Linux, probablemente el shell mas difundido sea el bash, por lo que estudiaremos el funcionamiento básico del mismo.

UTILIZANDO BASH EN FORMA INTERACTIVADebido a que la mayoría del tiempo, un usuario de linux debe tipear comandos, bash provee una serie de herramientas para hacer mas simple la interacción con el sistema, y minimizar los errores de tipeo. Una de las funciones mas simples y útiles las realiza la tecla TAB, permitiendo el autocompletado automático de nombres de archivos y comandos. Al ejecutar un simple “ls /bin”, nos encontramos con mas de 10 comandos que comienzan con la letra m, para evitar confusiones es posible tipear “ls /bin/m” y presionar la tecla TAB, el shell, en ese instante intentará expandir la expresión, autocompletando con aquel archivo en /bin que comienze con la letra m, pero como son múltiples los resultados posibles, el sistema responde con un "bip" y no ejecuta nada ... si volvemos a presionar la tecla TAB, forzamos a que el shell nos muestre todas las opciones disponibles para los archivos que cumplan con la expresion, dando por resultado algo similar a esto:

storage:~# ls /bin/mmbchk mkdir mktemp mount mt mvmkbimage mknod more mountpoint mt-gnu

UTILIZANDO EL HISTORIAL DE COMANDOSPara los desafortunados como yo, que sufrimos de problemas de memoria a corto plazo, bash ofrece muchas herramientas de ayuda. He aquí una situacion que me ocurre muy a menudo:

"Recuerdo hace unos dias haber ejecutado un comando complejo para, por ejemplo, contar la cantidad de usuarios diferentes logueados en el equipo, pero no recuerdo el comando, y no tiene sentido pensar 2 veces el mismo problema !!!"Ingresando el comando history, el sistema devuelve la lista de comandos ejecutados hasta el momento por el usuario actualmente logueado, esto incluye

Page 2: Shell power

tanto la sesion actual, como sesiones anteriores, por lo tanto podemos intentar encontrar el comando en la lista completa, mirando linea por linea o hacer una búsqueda un poco mas específica, si es que recordamos algún fragmento de lo que necesitamos encontrar. Supongamos que recuerdo que utilize el comando "who"; podría invocar al historial para consultar todos aquellos comandos ejecutados que incluyeran la palabra "who":

storage:~# history | grep who 502 who 503 who | cut -c1-8 | sort -u 504 who | cut -c1-8 | sort -u | wc -l

Una vez encontrado el comando buscado, se puede invocar a ejecutarlo por el numero de indice de la siguiente forma: (!numero de comando)

storage:~# !504who | cut -c1-8 | sort -u | wc -l

Simplemente el shell expande la expresión !nro de comando por la cadena literal que encuentre en ese índice del archivo del historial y envia la ejecución de la misma, obteniendo el mismo resultado que si se hubiera tipeado el comando completo.También es posible invocar a un comando recordando directamente parte de su nombre, por ejemplo

Ejecutar el ultimo comando que comience con " mysql "storage:~# !mysqlmysql -u user -p

REDIRECCION DE STDIN, STDOUT Y STDERRCualquier proceso en un sistema operativo *nix, necesita alimentarse de un dato de entrada, genera un nuevo PID en el S.O. y potencialmente puede producir una salida estándar y una salida de error.

/----- stdout (1) stdin (0) ----> PROCESO

\----- stderr (2)

El sistema operativo define por defecto cuales son los dispositivos que trabajan con la stdin, stdout, o stderr, obviamente por defecto, pero es posible manipular esto en forma manual.El caracter ">" simboliza la stdout, representada tambien por el entero 1. De esta forma, cualquier comando que genera una stdout puede ser forzado a que envie su salida a un dispositivo que no se el device por defecto, por ejemplo un archivo.De esta forma, se podria ejecutar, por ejemplo, un comando que lea el contenido del árbol de directorios del sistema y lo guarde en un archivo:

storage:~# ls -R / > /root/arbol-directorios.txt

En caso que el comando genere algun error, dado que la stdout sigue trabajando en el device por defecto, sería informado por pantalla.Para redireccionar la sdterr, representada por el entero 2, es necesario utilizar el simbolo "2>". Si un comando generara un error podría ser posible que estos se redireccionaran a, por ejemplo un archivo, de la siguiente forma:

storage:~# ls -R /noexisto 2> /root/arbol-directorios.txt

En el ejemplo, el directorio /noexisto, no existe en el sistema, por lo tanto el proceso ls genera salida por la stdout, y bash redirecciona la misma al archivo, por lo tanto por pantalla no se veran mensajes de error.Podria ocurrir que un determinado proceso genere información de salida tanto

Page 3: Shell power

estandar como de error, en ese caso se puede redireccionar cada elemento por separado, o bien ambos al mismo dispositivo, como se ve en el ejemplo:

storage:~# ls -R / /noexisto > /root-arbol-directorios.txt 2>/root/errores.log

En este ejemplo, se genera salida estandar que se redirecciona a un archivo y la salida de error se redirecciona a otro llamado errores.log

storage:~# ls -R / /noexisto > /root-arbol-directorios.txt 2>&1

En este ejemplo, tanto la salida estandar como la salida de error, son redireccionadas al mismo archivo. La expresión 2>&1 indica recireccionar la stderr al mismo device que la stdoutSería equivalente a escribir el comando redireccionando la stdout al mismo lugar que la stderr:

storage:~# ls -R / /noexisto 2> /root-arbol-directorios.txt >&2

Para redireccionamiento de la stdin se utiliza en simbolo "<", en el siguiente ejemplo se envia un mail con el asunto "redireccion de stdin", y el contenido del mail es el contenido de un archivo:

storage:~# mail -s "redireccion de stdin" [email protected] < /root/arbol-directorios.txt

Otro ejemplo de utilización de redirección de stdin podría ser al utilizar conexiones a bases de datos mysql directamente desde desde bash:

storage:~# mysql -u root -h localhost -p < /root/query.sql > /root/stdout.txt 2> /root/stderr.txt

En el ejemplo anterior se está utilizando el cliente de mysql conectándose al servidor ubicado en el equipo "localhost", con el nombre de usuario "usuario". La opcion -p permite que mysql pregunte la contraseña de conexión a la base de datos en forma interactva, para que no sea visible en pantalla ni quede ne los historiales de comandos de bash. Se redirecciona la sdtin con el objetivo de que el cliente mysql envie una consulta almacenada en el archivo /root/query.sql (ovbiamente en formato sql). Se redirecciona la stdout, es decir el resultado de la consulta al archivo /root/stdout.txt y los errores a /root/stderr.txt

EN SINTESISHemos estudiado solo algunas carácteristicas que hacen que la interacción entre usuario y sistema operativo *nix sea mas simple, practica y segura. El proceso de aprendizaje de uso correcto del shell lleva tiempo, practica y requiere un poco de lógica y sentido común, pero realmente obtendrá el máximo potencial del shell aprendiendo y utilizando comandos de unix no interactivos, pudiendo incluso combinar la potencia de estos comandos a traves de la “comunicacion entre procesos” a traves de pipes; pero por ahora concentrese en la operación básica del shell, que a solo a traves del uso encontrará inquietudes que lo llevaran a usted mismo a investigar sobre características mas avanzadas.

HISTORIA DE LOS SHELLSEl primer shell de caracteristicas avanzadas, programado para Unix se llamo sh, y fue incluido en el UNIX Version 7 en el anio 1979. Su creador fue Steven Bourne. Posteriormente Billy Joy programo el csh, el cual se popularizó debido a que utilizaba una sintaxis similar a la del lenguaje de programación C, muy popular en sistemas UNIX. EL csh fue mejorado y su version mas moderna se denomino tcsh Tenex C Shell. Tambien se popularizo otro llamado ksh o Korn Shell. A principios de 1988, el proyecto GNU lanzo su propia version de un shell, que combinaba las características de simpleza de uso del shell sh, con funciones avanzadas y manejo de expresiones al estilo de ksh y tcsh, combinando

Page 4: Shell power

en este nuevo producto las mejores caracteristicas de los shells mencionados. A este shell, en honor al creador del sh, se lo denomino bash (Bourne Again SHell).

ALGUNOS TRUCOS PRACTICOSExtras sobre historial de comandos:

El caracter “?” se puede utilizar como metacaracter para permitir enviar la ejecución de un comando que se encuentra en el historial. Por ejemplo:

storage:~# !?pablo?mail -s "redireccion de stdin" [email protected] < /root/arbol-

directorios.txt

Este comando busco en todo el historial por el ultimo comando que contiene la palabra “pablo”. Recuerde que !pablo intentaría buscar el ultimo comando que COMIENZE con la cadena.

Que pasaría si usted no esta seguro si el comando que quiere buscar es el ultimo en el historial ??. Afortunadamente bash permite que se ejecute una simulacion de ejecución, es decir buscar en el historial sin realmente ejecutar el comando, simplemente añada “:p” al comando de historial. Ejemplo:

storage:~# !vi:pvi /root/query.sql

El sistema responde con lo que ejecutaría si fuera a invocar el comando. Si estoy de acuerdo con el comando, solo hay que enviarlo a ejecutar normalmente:

storage:~# !vivi /root/query.sql

Práctico, no ?.

Bibliografia y links recomendados:"Learning the bash shell". Cameron Newham & Bill Rosenblatt. O'Reilly."Unix Power Tools". Peek, O'Reilly and Loukides. O'Reilly.The GNU Proyect: http://www.gnu.org

Lic. Pablo Gonzalez [email protected]