18 jul 2010

Comandos e intérpretes de comandos

Comandos/Shells

A quienes comenzaron en informática cuando Windows era ubicuo, les resultará raro interactuar con las máquinas por la escritura, pero así es UNIX, un entorno con el que se trabaja principalmente a través de órdenes escritas. Existen entornos de trabajo "de ventanas" para aumentar la productividad del usuario, pero se da por supuesto que un "usuario de UNIX típico" domina la línea de comandos (CLI), no teniendo por qué ser experto en la interfaz gráfica (GUI).

Comandos

Un comando es una instrucción que se le da al sistema para que éste efectúe una tarea (seguido de ENTER).

Ejemplo: Pedimos la fecha al sistema
luciag@pluton:~> date
Thu Jun 24 16:02:19 CEST 2010

Ejemplo: Pedimos a nuestro jefe un aumento de sueldo, enviándole una carta:
luciag@pluton:~> mail boss@company.com [menorque] raise_my_pay

En general la sintaxis de los comandos incluye opciones y argumentos.
comando [-opciones] [argumentos] ENTER

Los argumentos de los comandos UNIX tienen una sintaxis "consistente"

En UNIX no hay ficheros ejecutables según su extensión (como en Windows: .exe, .bat, .com)

Algunos comandos de UNIX

Además de los que hemos visto: finger, ls, echo, cat, tenemos muchos más comandos.

Si queremos más información sobre alguno de ellos o sus opciones siempre podemos hacer "man comando" (man es el comando que nos muestra el manual, whatis y apropos buscan en bases de datos para localizar lo que queremos buscar ).

Comando finger: Nos dice quien está conectado. finger "usuario" nos da más detalles. finger usuario@máquina nos da detalles de un usuario remoto. ¿Que no nos gusta lo que se dice sobre nosotros? chfn (En nuestro entorno este comando no funciona porque tenemos usuarios "de dominio NIS", entraremos en más detalle).
Comando who: Nos dice quien está conectado.
Comando id: Nos dice nuestro identificador de usuario.

Comando cat: Muestra el fichero
Comando more: Muestra el fichero con pausas.
Comando clear: El cls de UNIX.
Comando file: Nos dice de qué tipo es un fichero.

Comando uname: Para saber el tipo de máquina en que estamos. uname -a.
Comando hostname: Para saber el nombre de la máquina
Comando history: Vemos todos los comandos que hemos tecleado.
Comando env: Por si queremos ver todas nuestras variables de entorno.

Los comandos de manejo de ficheros y de procesos tienen su propia sección posteriormente.



Entrada y salida de los comandos

Los comandos realizan la labor encomendada, comunicándose con el usuario mediante la "entrada" (input) y la "salida" (output).

En el ejemplo de la fecha, la salida del comando es la fecha, visualizada en pantalla.
En el ejemplo de la carta, la entrada es el contenido del archivo con la solicitud.

De hecho tienen una entrada (standard input, identificada por el número 0) y dos salidas (standard output, identificada por el número 1 y standard error, identificado por el número 2).

Si queremos que la salida estándar de un comando se redirija a un fichero, usamos el carácter ">", mientras que usamos ">>" si queremos evitar que se machaque el contenido.

Ejemplo: Queremos que la fecha actual se guarde en un fichero.
luciag@pluton:~> date > fichero.txt

Ejemplo: Diez minutos después queremos volver a guardar la fecha actual, pero conservando la anterior:
luciag@pluton:~> date >> fichero.txt

Si el comando lleva a cabo su labor con "errores", la sintaxis es "diferente".

Ejemplo: El comando ls (listado) da una lista de los archivos que existen en el directorio actual, pero si le ponemos un argumento, muestra las características del mismo. Si pasamos un nombre de fichero que no existe al comando ls, nos dará un error. Si queremos redirigir este error a un fichero, no podemos utilizar solamente ">" o ">>"

luciag@pluton:~> ls noexiste > salida.txt
noexiste: No such file or directory

Y el fichero salida.txt no contiene nada.

¿Cuál es la solución a este problema? La sintaxis depende de la shell del usuario.
¿Y qué es una shell?


Shell o intérprete de comandos

La shell o intérprete de comandos es un programa que se carga en el entorno del usuario y que interpreta los comandos, individuales o en secuencia, que le estamos enviando.

Existen principalmente dos familias de shells: La de sh (Bourne Shell)/ksh (Korn Shell) y la de csh (C-Shell)/tcsh (Tenex C-Shell). Además en Linux existe una shell muy popular que es bash (Bourne Again Shell), que incorpora rasgos de las dos familias.

Cada usuario tiene una shell predeterminada, pero si queremos ejecutar en otra, basta con escribir el nombre del ejecutable.

Ejemplo: Vamos a ver qué shell tiene nuestro usuario del curso

luciag@pluton:~> finger curso
Login name: curso In real life: Usuario Cursos
Directory: /export/share/home/curso Shell: /usr/local/bin/tcsh
Never logged in.

luciag@pluton:~> bash
bash-2.03$

Volviendo al ejemplo anterior, para redirigir el error a un fichero, la sintaxis para cada una de estas familias de shells es:

$csh> comando >& salida.txt
$ksh> comando > salida.txt 2>&1

Así que para que los errores acaben en el fichero, en nuestro usuario, que tenemos tcsh:

luciag@pluton:~> ls noexiste >& salida.txt

Hay un comando que muestra el contenido de un fichero, el comando cat. Con esto podemos comprobar que el resultado ha acabado en el fichero que pedimos.

luciag@pluton:~> cat salida.txt
noexiste: No such file or directory

Podemos usar cat para copiar nuestro fichero a otro fichero. ¿Cómo?
luciag@pluton:~> cat salida.txt > otrofichero.txt

Tuberías

Las tuberías son órdenes que nos permiten enchufar la salida de un comando, a la entrada del comando siguiente. Lo bonito de UNIX es que lo que hace un comando lo pueda entender otro.

Una tubería, simbolizada por una barra vertical (carácter "|"), permite asignar la salida estándar de un comando a la entrada estándar de otro, de la misma forma en que una tubería permite la comunicación entre la salida estándar del lavabo enchufándolo a la entrada estándar del desagüe.

Ejemplo: El comando ls lista todos los ficheros que tenemos en el directorio actual. Para ver el listado con opciones, el comando es ls -l. El comando para ordenar es sort. Si queremos ver la salida ordenada del listado con detalles escribiríamos:

luciag@pluton:~> ls -l | sort


Ejemplo: El comando ls lista todos los ficheros que tenemos en el directorio actual. Para ver el listado con opciones, el comando es ls -l. El comando para ordenar es sort. Si queremos ver la salida ordenada del listado con detalles escribiríamos:

Teclas de control y caracteres especiales en la shell

Si un comando se nos "cuelga" un poco podemos interrumpirlo mediante CTRL-C (Cancel)
Para pausar y despausar la ejecución de un comando CTRL-S/CTRL-Q (Suspend/Quit)
Si queremos que la ejecución siga pero nos deje escribir mientras, CTRL-Z.

El carácter ; separa comandos como si estuvieramos en líneas distintas
Ejemplo: El comando echo reproduce la cadena indicada. Con el ; lo podemos ejecutar dos veces.

luciag@pluton:~> echo hola; echo adios
hola
adios

Productividad al teclado.

La shell tcsh puede autocompletar comandos y argumentos (aunque no opciones) usando la tecla TAB. Si escribes la primera o segunda letra del comando o argumento seguido de TAB, el shell completa el resto de la palabra (si existe una única opción) o completa en forma parcial la palabra y emite un pitido para indicar que existen más opciones. En este momento pueden ayudar al shell escribiendo una o más letras y volver a escribir TAB o puedes escribir ctrl-D (^D) para ver la lista de opciones que tiene el shell para completar.

Algunas opciones para moverse por la línea de comandos son:





Ctrl-aIr al principio de la línea de comandos
Ctrl-eIr al final de la línea de comandos
Ctrl-kCortar los caracteres a la derecha del cursor
Ctrl-yPegar los caracteres anteriores




Perfiles

El perfil es un fichero que se carga cuando abrimos una conexion con el sistema, aunque también cuando nos conectamos como otro usuario, o ejecutamos un script. La sintaxis del perfil depende del tipo de shell y de si ésta es interactiva o no.

Shell interactiva y shell no interactiva


Una shell interactiva es la que abrimos, por ejemplo, cuando nos logamos, que tiene asociada una terminal, mientras que u
na shell no interactiva es la que abrimos por ejemplo cuando realizamos un rsh sistema comando, o escribimos un script.

Una shell interactiva se consigue pasando como primer argumento el signo "-" (menos).

Cuando ejecutamos una shell no interactiva, después del fichero del sistema /etc/csh.cshrc (en tcsh) y /etc/profile (en ksh) se carga el fichero .cshrc (en tcsh) y .profile (en ksh).
Sin embargo cuando ejecutamos una shell interactiva, además se carga el fichero .login (en tcsh).

Por eso si yo en el inicio del usuario quiero incluir opciones:
- Las cosas interactivas tienen que ir en el .login
- Las cosas no interactivas tienen que ir en el .cshrc

Si yo quiero recargar lo que he escrito en mi .profile (ksh) o mi .cshrc (tcsh) no tengo más que:

ksh~> . .profile
csh
~> source .cshrc

En Bash que es un mixto de ksh y tcsh, primero se mira el /etc/profile y luego el .bashrc, pero si es interactiva se ejecuta el .bash_profile. Para evitar volvernos locos podemos simular el comportamiento de la tcsh con una línea como esta en
.bash_profile

if [ -f ~/.bashrc ]; then source ~/.bashrc fi

Variables de entorno

Una variable de entorno es un valor compartido por los procesos que se inician desde el entorno de un usuario (de ahí el nombre)

La sintaxis para ver el valor de una en concreto es mediante el carácter $ (dólar), y para fijarla depende de la shell. Por ejemplo, la variable de entorno HOST se muestra así

luciag@luna.acme.com:/usr/bin> echo $HOST
luna.acme.com

En csh/tcsh

$csh>
setenv VARIABLE valor
$csh>
echo $VARIABLE

En ksh/bash

bash-3.2$ export VARIABLE=valor
bash-3.2$ echo $VARIABLE
valor

Variables locales, variables de shell

Las variables de entorno se definen tipicamente en el fichero de inicio como .profile o .cshrc.

Cuando creo una shell nueva se suelen transferir a ésta (por ejemplo en un script) a menos que las defina como variables locales. Por ejemplo, HOME, TERM, DISPLAY...

Las variables locales no se transfieren a las shells nuevas cuando éstas se crean.

En tcsh estas suelen distinguirse por escribirse con letras minúsculas, como prompt, history o savehist.
En ksh o bash todas las variables son locales a menos que las exportes.

tcsh

$csh>
set something=anotherthing Variable local o de shell
$csh> setenv SOMETHING anotherthing Variable de entorno

ksh

$ksh> SOMETHING=anotherthing Variable local
$ksh> export SOMETHING La hemos exportado al entorno


El PATH

El PATH es una variable de entorno que se utiliza para determinar las ubicaciones en las cuales la invocación de un comando encuentra a su ejecutable.
El LD_LIBRARY_PATH (Solaris o Linux, en AIX LIBPATH), es una variable de entorno que utiliza el ejecutable para encontrar las librerías dinámicas de las que depende.

# ksh
export PATH=
/usr/local/X11R6.3/bin
:${PATH}
export LD_LIBRARY_PATH=
/usr/local/X11R6.3/lib
:
${LD_LIBRARY_PATH}

# tcsh
set path = ($path /usr/local/X11R6.3/bin)
setenv LD_LIBRARY_PATH "$LD_LIBRARY_PATH":/usr/local/X11R6.3/lib:/usr/dt/lib

Esta es la manera típica de hacerlo en tcsh (set en lugar de setenv) porque la shell autoexporta de la variable de shell a la variable de entorno.

Atajos y configuración de la shell

Tanto en ksh como en tcsh existen atajos para mayor rapidez. Por ejemplo, en tcsh.

Para sacar la historia, usamos el comando de shell history
$csh> history

Para repetir el último comando que empezó de cierta forma, usamos la !
$csh> cls
$csh> !c

El comportamiento de la shell se puede modificar en muchos sentidos, a través de variables de shell. Por ejemplo, en tcsh la variable de shell autologout puede ser configurada para que la sesión se desconecte automáticamente después de un cierto número de minutos de inactividad.

# Inactividad: contraseña a los 120 minutos, salida a las 5 horas.
set autologout = (350 120)

En general, para aprender más de nuestra shell, siempre podemos recurrir al manual.

man ksh
man tcsh
man bash

En una sección posterior trataremos el scripting en Korn Shell.

Bibliografia
http://en.wikipedia.org/wiki/Tee_%28command%29
http://en.wikipedia.org/wiki/List_of_Unix_programs

http://genoma.unsam.edu.ar/bioinformatica2005/unix.html


Ejercicio
Configurar la variable de entorno DISPLAY con el valor del nombre de nuestra máquina virtual Fedora12.
Hacerlo en la máquina (el usuario local tiene bash) y también en la máquina remota (el usuario curso tiene tcsh). ¿Por qué no podemos abrir un editor gráfico desde la máquina remota a la máquina local?


No hay comentarios:

Publicar un comentario