Está en la página 1de 27

INTRODUCCION y CONCEPTOS BASICOS

El sistema operativo UNIX


Un sistema operativo es un programa que controla otras partes del ordenador tanto hardware como software.
Permite además al usuario acceder a las facilidades que ofrece el sistema.
UNIX comienza en 1969 como un proyecto de investigación de Bell Laboratories, estando disponible la
primera versión comercial en 1977 y ganando rápidamente en popularidad y difusión.
Los objetivos que persiguieron los primeros diseñadores de UNIX fueron conseguir un sistema operativo que
permitiera un desarrollo eficiente de programas, que fuera pequeño y eficiente en el uso de la memoria y fácil
de mantener.
Los sistemas operativos, hasta la aparición de UNIX, eran pensados para funcionar únicamente en el
sistema en que eran desarrollados. Esto implicaba un gran esfuerzo en aprender un nuevo sistema operativo
cada vez que se usaban sistemas distintos. Aplicaciones que funcionaban en un sistema no estaban
disponibles en otros e incluso los propios programas requerían modificaciones para transportarlos a otro
sistema.
Una de las razones que han hecho que UNIX haya alcanzado una gran popularidad es resolver estos
problemas, pues permite transportarlo fácilmente a diferentes sistemas. Esto se consiguió diseñando el
sistema operativo de forma que hiciera muy pocas suposiciones sobre la arquitectura de la computadora y
escribiendo la mayor parte del sistema operativo en un lenguaje de alto nivel (C). Sólo una pequeña parte (el
kernel) está escrito en lenguaje ensamblador.
Actualmente UNIX puede ser usado desde pequeños ordenadores personales a grandes computadoras. Así
pues un programador puede encontrar las mismas herramientas de programación, entornos similares y
ejecutar fácilmente sus programas en cualquier sistema que use UNIX.
No hay una única versión de UNIX. En la actualidad existen dos versiones principales: System V (la más
popular y es la usada en el IAC) y la BSD. Con pequeñas diferencias en la estructura de ficheros y en
algunos comandos. En el IAC la red UNIX usa como sistema operativo la versión de UNIX de Sun
Microsystem llamada SunOS. Hay varias versiones del sistema operativo. A partir de la versión SunOS 5.0
se distribuye como Solaris version 2.
SunOS 5.4 = Solaris 2.4
SunOS 5.5 = Solaris 2.5
No todas las máquinas del IAC tienen la misma versión.
Al entrar en nuestra cuenta en el IAC tenemos fundamentalmente dos opciones:
Common Desktop Enviroment (CDE).
OpenWindows (OW).
No hay que confundir estas dos opciones con versiones del sistema operativo. Los sistemas de ventanas son
utilidades que usualmente se distribuyen con el sistema operativo para facilitar la forma que tiene el usuario
de interactuar con el sistema operativo (GUI Grafical User Interface), pero no forman parte del sistema
operativo.

Partes del sistema operativo


Las partes más importantes en que puede dividirse el sistema operativo UNIX son:
Kernel
Shell
UNIX file system
Además, normalmente con el sistema operativo se suministran otra serie de programas, utilidades para
comunicaciones, editores, lenguajes de programación, etc, que no forman parte estrictamente del sistema
operativo.

Kernel
Puede considerarse como el núcleo del sistema operativo y es leido cada vez que se inicializa el sistema.
Realiza una serie de tareas básicas como son:
 Controlar la memoria de la máquina y asignar una parte a cada proceso
 Distribuir el trabajo realizado por la CPU de forma que sea lo más eficiente posible
 Organizar la transferencia de datos entre las distintas partes del sistema
 Aceptar las instrucciones de la shell
 Hacer cumplir los permisos especificados en el sistema de ficheros
Shell
La forma que el usuario tiene de acceder a los servicios del kernel es mediante la shell. Se puede considerar
como el interprete de comandos, que permite que los comandos y programas que tecleamos sean
ejecutados.
En UNIX hay varios tipos de shell que ofrecen diferentes características:
 Bourne shell (sh)
 C shell (csh)
 TC shell (tcsh)
 Korn shell (ksh)
 Bourne Again SHell (bash)
Bourne shell. Es la original de UNIX y está disponible en todos los sistemas, sin embargo no ofrece las
facilidades de interacción con el usuario que ofrecen las shell más modernas.
C shell. Es la que tenemos normalmente cuando nos abren la cuenta en el IAC, (aunque podemos pedir que
nos pongan otra).
TC shell es similar a la anterior pero ofrece más facilidades para editar la línea de comandos de forma
interactiva. En lo que resta del curso supondremos que estamos trabajando con la TC o C shell.
Korn shell y Bourne Again SHell proporcionan las facilidades de interacción de TC shell pero el lenguaje de
programación en shell es más parecido al original Bourne shell que a TC o C shell.
En la tabla se muestra un resumen de las características más importantes de las distintas shells.
Bourne C TC Korn BASH ________________________________________________________
command history No Yes Yes Yes Yes
command alias No Yes Yes Yes Yes
shell scripts Yes Yes Yes Yes Yes
filename completion No Yes* Yes Yes* Yes
command line editing No No Yes Yes* Yes
job control No Yes Yes Yes Yes ________________________________________________________
* Esta opción no está puesta por defecto
Para cambiar de shell basta con teclear en la línea de comandos el nombre de la shell que deseemos
(sh, csh, tcsh, ksh o bash). Sin embargo no podemos cambiar la opción que tenemos por defecto al entrar en
la cuenta, si queremos cambiarla hay que pedirlo al administrador del sistema.

UNIX file system


La tercera parte que define el sistema operativo UNIX es la estructura de su sistema de ficheros.
Un sistema de ficheros es la forma que tiene el sistema operativo de organizar los datos en una estructura o
colección de ficheros. UNIX considera como ficheros no sólo a los ficheros normales (en los que guardamos
datos, programas, etc) sino también a los directorios y los dispositivos conectados al sistema.
El sistema de ficheros en UNIX está organizado en una estructura jerárquica de directorios que comienza en
el directorio root representado por / .
Los directorios que cuelgan de root pueden variar dependiendo del sistema, aunque los mostrados en el
arbol a continuación, sí son comunes a todos los sistemas UNIX.
/(root)
|
----------------------------------------------------
| | | | | | |
/bin /dev /etc /home /lib /tmp /usr

 /bin contiene comandos y utilidades, son ficheros ejecutables


 /dev contiene los ficheros que representan a los dispositivos conectados al sistema
 /etc contiene comandos y ficheros usados en la administración del sistema
 /home contiene los ficheros home de cada usuario del sistema
 /lib contiene librerías utilizadas por diferentes programas y lenguajes
 /tmp es el directorio donde se guardan los ficheros temporales
 /usr contiene ficheros del sistema que son comunes a los usuarios como programas o
documentación.
Los ficheros pueden clasificarse dentro de las siguientes categorías:
 Ficheros normales
 Directorios
 Ficheros especiales
 Pipes
Los ficheros normales pueden tener contenidos muy diferentes, por ejemplo texto, imágenes, ejecutables,
etc. Todos los ficheros tienen un propietario, los que creamos nosotros desde nuestra cuenta nos pertenecen
y cada propietario es el que puede controlar los permisos de acceso a ese fichero.
Los directorios son ficheros que contienen referencias a otros ficheros. Aunque todos los ficheros se
encuentran dentro de algún directorio, no residen realmente dentro de él. El directorio mantiene dos
informaciones básicas sobre cada fichero contenido en él: El nombre y un número llamado inode number que
es un puntero que le indica al sistema donde encontrar toda la información que necesita del fichero.
A la correspondencia entre el nombre de un fichero y el inode number se le denomina link. Un mismo inode
number puede tener asociados varios nombres y nos podemos referir al fichero por cada uno de estos
nombres.
Los dispositivos especiales son ficheros que representan dispositivos físicos como impresoras, dispositivos
magnéticos, el ratón, etc. Se encuentran dentro del directorio /dev. Por ejemplo, si la salida por pantalla de
un programa no nos interesa podemos enviarla al dispositivo /dev/null que en realidad no tiene un dispositivo
físico asociado, perdiendose de esta forma la salida del programa.

programa1 >/dev/null

Los pipes permiten enlazar la salida de un comando a la entrada de otro, esto se hace a través de la
creación de un fichero temporal donde se guarda la salida del primer programa hasta que es leido por el
segundo.
COMANDOS
Lo primero que necesitamos es tener una cuenta. Cuando el administrador del sistema nos abre una cuenta
nos dará un username y un password. Para entrar en la cuenta escribimos nuestro username donde
pone login. Luego nos pide el password. Tanto el username como el password son sensibles a mayúsculas o
minúsculas.
Una vez dentro de la cuenta utilizamos una terminal (por ejemplo una xterm) para ejecutar los comandos.
Podemos empezar por cambiar el password que nos ha dado el administrador del sistema con el comando:
nispasswd
que nos pedirá nuestro password anterior y el nuevo (lo pide dos veces para evitar errores). La elección
del password, por razones de seguridad, debe evitar palabras de diccionarios, es conveniente mezclar
números con letras o algún caracter especial.
Sintaxis de los comandos
La forma básica de un comando unix consta de tres partes aunque no todas tienen que estar presentes. La
primera, que es necesaria siempre, es el nombre del comando. Luego vienen las opciones que son letras
que se ponen precedidas del signo - y que le indican al comando que opción deseamos (algunas de estas
opciones requieren un argumento). Por último están los argumentos del comando que pueden ser opcionales
o no dependiendo del comando en concreto. Si cometemos errores en la sintaxis, como una opción
inexistente, se nos indicará por pantalla cual es la sintaxis de ese comando con sus opciones y argumentos,
indicando entre corchetes [] los que son opcionales. También podemos ver la sintaxis en la ayuda del
comando. Un ejemplo de comando con opciones y argumentos es:
ls -la dir1l

Comandos más usados


Hay una serie de comandos que se usan muy frecuentemente que se describen brevemente en las
siguientes secciones.
man
Nos permite obtener ayuda sobre cualquier comando (man nos muestra la página del manual
correspondiente al comando).
Típicamente las secciones que trae la ayuda son:
 NAME
 SYNOPSIS
 DESCRIPTION
 OPTIONS
 ENVIRONMENT
 EXAMPLES
 FILES
 SEE ALSO
 WARNINGS
 DIAGNOSTICS
 BUGS
por ejemplo ejecutando:
man man
Se nos muestra la página de ayuda sobre el comando man. En la sección SYNOPSIS se nos muestra las
distintas opciones que tiene el comando.
Utilizando la opción -k en el comando man y una palabra clave o frase entre comillas, mostrará el nombre de
todos los comandos que en la sección name incluyen esa palabra o frase. Por ejemplo para buscar que
comandos pueden servir para copiar ficheros:
man -k 'copy files'
Otra forma de consultar el manual es con el comando xman que nos abre una ventana donde tendremos
diferentes opciones. También podemos utilizar en las SUNs el comando answerbook que nos abre un
"navegador" donde podemos consultar diferentes documentos no sólo de UNIX (en la nueva versión de
Solaris instalada en el instituto ya no esta disponible este comando sino answerbook2 que nos saca la
ayuda en Netscape).
Comandos básicos relacionados con directorios
pwd
Nos muestra el directorio en que estamos trabajando.
ls
Nos muestra los ficheros contenidos en un directorio. Tiene varias opciones muy útiles como -l para un
formato largo con una serie de características de cada fichero. La opción -a muestra los ficheros ocultos
(ficheros que empiezan por el caracter .). Se puede ordenar la salida por diferentes opciones como por fecha
o alfabéticamente.
La información que nos muestra cuando empleamos la opción -l es:
 Una serie de 10 caracteres donde el primero nos informa del tipo de fichero que es y los nueve
restantes sobre los permisos que tiene el fichero.
 Un número que indica el número de links al fichero.
 El propietario.
 El grupo al que pertenece.
 El tamaño en bytes
 La fecha de la última modificación
 El nombre del fichero (si es un link simbólico se muestra también el fichero al que hace referencia).
Este comando y otros como cp, rm, etc pueden usar una serie de caracteres llamados "wildcards" que nos
permiten seleccionar ficheros que siguen un cierto patrón en su nombre. Estos caracteres son:
* Representa cualquier cadena de carcteres
? Representa un sólo caracter
[...] Podemos poner dentro una lista de caracteres que son los posibles para un solo caracter.
Ejemplos:
cp * ~/textos
Copia todos los ficheros del directorio actual al subdirectorio textos de mi home.
Si tenemos una serie de ficheros cap1.tex cap2.tex cap3.tex capitulo.tex, el comando
mv cap?.tex ~
nos moverá los tres primeros a nuestro home.
ls b[Aa]*
Nos hará una lista de todos los ficheros cuya segunda letra sea una A o a y empiecen por b. En los corchetes
puede incluirse un rango como por ejemplo [0-5] [a-z] [A-Z], que respectivamente significan cualquier número
del 0 al 5, cualquier letra minúscula y cualquier letra mayúscula.
mkdir
Nos crea un nuevo directorio.
rmdir
Borra un directorio.
cd
Cambia de directorio. Se puede dar la ruta completa al directorio (cd /home/...) o podemos darla relativa al
directorio en que estamos (este directorio se representa por el caracter . mientras .. representa el
inmediatamente superior). También podemos dar la ruta relativa a nuestro home con el caracter ~ (cd
~/texto). Para ir a nuestro home basta con ejecutar cd sin argumentos.
Comandos básicos relacionados con el manejo de ficheros
cp
Es el comando para copiar ficheros, por ejemplo:
cp unix.tex ~/curso/texto.tex
copia el fichero unix.tex a /home/fcabrera/curso/ cambiandole el nombre a texto.tex . La opción -i nos
preguntará si queremos que sobreescriba en el caso de que el nombre del fichero coincida con el de otro
fichero que ya existe. La opción -r permite copiar directorios incluyendo todos los ficheros y directorios que
cuelgan de él.
mv
Es similar al comando anterior pero no hace una copia sino mueve el fichero (lo cambia de nombre).
También está disponible la opción -i.
rm
Borra ficheros. También está la opción -i que nos pide confirmación para borrar cada fichero y la opción -
r para borrar todos los ficheros que cuelguen de un directorio.
ln
Permite realizar links entre ficheros. Cada fichero tiene un inode number y al menos un nombre. La
correspondencia entre un inode y el nombre es un link y podemos asociar varios nombres a un mismo
fichero. Para crear un link ejecutamos el comando:
ln filename1 linkname
Se puede también hacer un link de varios ficheros a un directorio. Sin embargo no podemos hacer links entre
directorios, esto sólo lo puede hacer el super-user. Si queremos hacer un link entre directorios hay que
utilizar la opción -s que crea lo que se llama un link simbólico. Por ejemplo para hacer un link simbólico a un
directorio llamado /net/oso/scratch/fcabrera desde nuestro home llamandolo scratch sólo tenemos que
situarnos en nuestro home y ejecutar:
ln -s /net/oso/scratch/fcabrera scratch
Ahora tendremos en el home un directorio scratch que al acceder a él acccedemos
a /net/oso/scratch/fcabrera . No es una copia de este directorio sino que físicamente sólo existe el
directorio en el disco. También es necesario usar la opción -s entre ficheros normales, si se encuentran en
dispositivos físicos distintos. Para borrar un link se usa el comando rm que no borra el fichero sino el link a
ese fichero. Por ejemplo:
rm scratch
no borra el directorio sino el link a /net/oso/scratch/fcabrera.
find
Permite buscar un fichero en la estructura de directorios. Hay varias opciones de busqueda como por
ejemplo para buscar los ficheros con un determinado nombre, ficheros que tengan un determinado tamaño,
que hayan sido modificados en los últimos n dias etc. Por ejemplo:
find . -name text
buscará cualquier fichero que se llame text que se encuentre en el directorio actual o cualquiera que cuelgue
de él.
Otro ejemplo que muestra una sintaxis más complicada es el siguiente:
find . \( -name a.out -o -name '*.o' \) -mtime -3 -exec rm {} \;
Que borrara los ficheros a.out y los que terminen en .o que han sido modificados en los últimos 3 dias. La
barra \ antes del paréntesis es para evitar que la shell le de un significado especial, las comillas son
necesarias cuando se utilizan wildcards en los patrones de busqueda.
Comandos útiles para trabajar con ficheros de texto son:
page y more
Para mostrar un fichero por pantalla de forma que espere cuando el terminal este lleno a que pulsemos
alguna tecla.
cat
Encadena una lista de ficheros escribiendolos uno a continuación de otro en la salida estandar.
grep
Busca un patrón de caracteres en uno o varios ficheros. Nos mostrara las lineas en que encuentre el patrón y
si la busqueda se realiza en más de un fichero nos indica primero el nombre del fichero. Por ejemplo el
comando:
grep -i galaxia *.tex
Nos motrara cada linea que contenga la palabra galaxia en cualquier fichero con extensión .tex, indicando en
que fichero se encuentran. La opción -i indica que no importa si es en mayusculas o minusculas.
sort
Permite ordenar las líneas de uno o varios ficheros, hay varias opciones para realizar la ordenación. Por
ejemplo:
sort l1 l2 +1
ordena los ficheros l1 y l2 por la segunda palabra (+1) y la salida es dirigida a la salida estandar.
diff
Muestra las diferencias línea pínea de dos ficheros de texto.
cmp
Compara dos ficheros y nos muestra el byte y número de línea donde ocurre la primera diferencia.
head y tail
El comando head muestra las n primeras líneas de un fichero y tail las últimas líneas.
Comandos útiles para examinar el espacio en disco memoria, procesos, usuarios, etc
df
Para ver la cantidad de espacio en disco. La opcion -k nos lo da en kilobytes.
du
Nos da la cantidad de disco usado por el directorio y todos los subdirectorios que cuelgan del directorio
especificado. La opción -k nos lo da en kilobytes.
quota
Con la opción -v nos muestra la cantidad de espacio que tenemos de cuenta en el home y la que tenemos
ocupada.
top
Nos muestra en pantalla los procesos que ocupan más CPU con el porcentaje correspondiente, así como
otras informaciones como memoria de la máquina, memoria utilizada. La información se va actualizando
periodicamente.
ps
Nos permite ver los procesos que se están ejecutando.
who
Para saber quien está conectado a la máquina en la que estamos trabajando.
rusers
Nos muestra quien está en cada máquina del sistema. La opción -l nos da información más detallada de
cada uno.
whereis o which
Localiza un comando, es decir nos muestra la ruta de acceso del fichero ejecutable.
finger
Muestra información sobre los usuarios como username, nombre completo, cuando a leido su mail por última
vez, si está o no conectado y desde donde, etc. Podemos crear un fichero en nuestro home con el
nombre .plan cuyo contenido se mostrará cuando alguien haga un finger. Podemos utilizar el username si lo
sabemos, o bien buscar por el nombre o apellidos reales.
Redirección de comandos y pipes
Redirección de comandos
Cualquier dispositivo conectado al sistema (impresoras, terminal, dispositivo de audio, mouse, etc), es
considerado por UNIX como un fichero.
Los comandos pueden necesitar leer y escribir información. Normalmente lo hacen en la standard
input y standard output que es el terminal. Sin embargo ambas pueden redireccionarse a otros ficheros, tanto
ficheros normales como dispositivos físicos.
Para redireccionar la entrada estandar se usa < seguido del nombre del fichero. Por ejemplo:
mail fcabrera < file1
Envía un mail a fcabrera tomando como texto el cotenido del fichero file1.
Para redireccionar la salida estandar hay varias opciones (>, >&, >!, >&!, >>, >>&, >>!, >>&!) seguido del
fichero al que se dirige la salida.
> Envía el resultado del comando a un fichero reescribiendolo, si se añade & se envían también los erroes, si
se añade ! se asegura que se pueda escribir al fichero aunque tengamos definida la variable noclobber que
evita la sobrescritura.
>> Envía el resultado a un fichero pero añadiendolo al final. En este caso si esta definida la
variable noclobber se produciría un error si el fichero no existe previamente, a menos que añadamos !.
Ejemplos:
cat sound.au > /dev/audio
Enviará el fichero de sonido sound.au a /dev/audio, que es el fichero asociado al dispositivo de audio.
crypt zyxst < texto > texto.crypt
Este comando toma como entrada el fichero texto, lo codifica con la clave zyxst y lo escribe en el
fichero texto.crypt.
Pipes
Se denomina un "pipeline" a una serie de comandos separados por | o |&. En el primer caso la salida
estandar del primer comando es direccionada a la entrada del segundo, mientras |& redirecciona la salida
estandar y los errores.
Los pipelines y los comandos pueden separarse por ; y se ejecutan secuencialmente, o pueden separarse
con condicionales. && ejecuta el segundo pipe si el primero se ejecuta sin errores (standard error es
0). || ejecuta el segundo pipe si se produce un error en la ejecución del primero (standard error distinto de 0).
Ejemplos:
Para contar el número de usuarios de la máquina en que estamos trabajando
who | wc -l
who tiene como salida una línea con información por cada usuario conectado a la máquina. Esto es enviado
a la entrada del comando wc -l, que cuenta el número de líneas.
El siguiente ejemplo muestra los procesos ordenados por el porcentaje de CPU que emplean.
ps -feao ruser,pid,pcpu,etime,comm | sort -r +2 | more
ps muestra los procesos en un determinado formato, el resultado es ordenado por el comando sort y se
muestra por pantalla empleando el comando more.
El ejemplo:
tar -cvf /dev/rmt/0lbn . || (tar -cvf /scfratch/fcabrera/backup .; compress backup; cp ) &
Primero produce un backup del directorio en que estamos en un dispositivo magnético. En caso de que
fallara se haría un backup al disco de scratch y lo comprime para ahorrar espacio.
El uso de las comillas en UNIX
UNIX trata de forma diferente los caracteres especiales dependiendo de si sencuentran entre comillas, y del
tipo de comillas que sean. Vamos a ver varios ejemplos utilizando el comando echo, que simplemente
escribe sus argumentos en la salida estandard separados por espacios y terminando con un retorno de línea.
Las dobles comillas
Veamos los siguientes ejemplos:
echo *
echo "*"
En el primer caso la shell sustituye * por los nombres de todos los ficheros en ese directorio separadeos por
espacios. En el segundo caso el resultado nos muestra por pantalla el caracter *. Esto se debe a que las
comillas impiden la sustitución de * por nombres de ficheros tratandolo como un caracter sin significado
especial.
Otros caracteres que pierden su significado especial entre las comillas son *, ?, >, <, >>, |. Además las
dobles comillas también mantienen el significado de los espacios en blanco.
Comillas simples
El uso de las comillas simples puede producir resultados diferentes como por ejemplo:
echo $shell
echo "$shell"
echo '$shell'
Los dos primeros casos tienen el mismo efecto y muestra por pantalla el valor de la variable shell. Esto se
debe a que el caracter $, que sirve para referirse al valor de una variable, no pierde su significado dentro de
las dobles comillas. Sin embargo esto si sucede dentro de las comillas simples y el resultado en el tercer
caso es mostrar por pantalla $shell. También pierden su signicado los caracteres especiales que pierden su
significado en las dobles comillas, así como las dobles comillas.
El caracter \
Este caracter sirve para quitar cualquier significado especial que tenga para la shell el caracter que va a
continuacion de \ . Por ejemplo:
echo \$shell
como resultado muestra por pantalla $shell.
Las comillas simples invertidas
El significado de las comillas invertidas es completamente diferente. Se emplea encerrando en estas comillas
un comando y el resultado es ejecutar el comando insertando la salida en el punto de la línea de comandos
donde se encuentra el comando. Por ejemplo:
echo La fecha de hoy es `date`
man `ls`
En el primer caso se ejecuta el comando date insertando el resultado al final de la frase. El segundo dará
probablemente error, pues tratará de buscar una página del manual de ayuda para comandos que se llamen
como cada uno de los ficheros del directorio. A no ser que algún fichero tenga nombre de comando, el
resultado será que no encuentra la página del manual para cada nombre de fichero. Las comillas invertidas
mantienen su significado dentro de las dobles comillas, pero no dentro de las comillas simples.
CONFIGURACION DEL ENTORNO
El entorno de trabajo queda definido mediante los valores que la shell encuentra en los ficheros de
inicialización que se leen cada vez que entramos en la cuenta o empezamos una nueva shell. En general en
los ficheros de configuración suelen definirse variables locales (o de shell) y variables de entorno, definir alias
e incluir comandos que queramos que se ejecuten al entrar en la cuenta o la nueva shell.
Nos centraremos en la C shell y TC shell que son las más comunes. Los ficheros de configuración básicos
que se leen cuando entramos en la cuenta son el .cshrc (o .tcshrc para la TC shell) y el .login . Cuando se
inicia una nueva shell sólo se lee el primero. Estos ficheros deben estar en el home y al empezar por . son
ficheros ocultos.
Hay que distinguir entre dos tipos de variables: las variables locales y las de entorno. Las primeras sólo
tienen validez en la shell en las que están definidas. Las segundas son heredadas por cualquier shell que se
ejecute aunque estas variables hayan sido definidas en el .login que no se lee al abrir una nueva shell.
Los comandos básicos para la definición de variables son, set, setenv, unset, unsetenv.
set
Este comando se utiliza para definir las variables locales, su sintaxis es:
set varname = value
set varname
En el primer caso asignamos un valor a una variable esté o no definida anteriormente, por ejemplo:
set prompt="(%M)%~%% "
define lo que aparece al principio de la línea de comandos. %M es el hostname. %~ El directorio en el que
estamos pero representando nuestro home por ~ y %% añade el caracter % al final. Cada shell usa símbolos
distintos para definir el prompt,.
En el segundo caso simplemente se define una variable. Por ejemplo:
set noclobber
define la variable noclobber. Si esta variable esta definida no permitirá sobreescribir un fichero si
redireccionamos la salida de un comando a un fichero que ya existe.
Para ver el valor de una variable ya vimos que se puede hacer con el comando echo. Por ejemplo:
echo $PATH
Mostrará el contenido de la variable de entorno PATH (esta variable contiene las rutas de accesos donde la
shell buscara los ficheros ejecutables. Seguirá el orden en que los directorios aparezcan en el PATH). Sin
embargo, si queremos ver todas las variables que tenemos definidas ejecutamos set sin argumentos.
setenv
Se emplea de forma análoga a set pero con variables de entorno. La sintaxis es ligeramente diferente:
setenv varname value
(sin el signo =). Podemos asignar un valor a una variable, simplemente definirla, o ver las variables de
entorno que tenemos definidas ejecutando setenv sin argumentos.
setenv TAPE /dev/rmt/0bn
Define la variable TAPE como /dev/rmt/0bn .
unset y unsetenv
Sirven para borrar variables locales y de entorno respectivamente, que ya estaban definidas. La sintaxis es:
unset varname
unsetenv varname
¿Donde definir las variables?
Cada vez que empezamos una nueva shell se ejecuta un fichero de configuración que depende de la shell en
cuestion:
Bourne Shell .profile
C Shell .cshrc
TC shell .tcshrc
Korn Shell .kshrc
BASH .bashrc
Es en estos ficheros donde debemos definir las variables locales que se las llama también variables de la
shell. Por convención para estas variables se usan letras minúsculas mientras para las variables de entorno
se suelen usar mayúsculas. Hay que tener en cuenta que en cada shell hay variables que tienen significados
especiales solamente en esa shell, por esto la definición de estas variables debe hacerse en estos ficheros y
no en el .login.
En el fichero .login en general suelen definirse las variables de entorno, aunque pueden definirse en el
fichero de inicialización de la shell correspondiente.
Una vez dentro de una shell (supongamos TC shell) podemos definir nuevas variables ejecutando los
comandos set o setenv. o bien incluyendo estos comandos en el fichero .tcshrc y volviendolo a ejecutar con
el comando source.
source .tcshrc
Alias
Otra de las utilidades que permiten tener un entorno de trabajo más agradable es la definición de alias. Un
alias nos permite asignar un nuevo nombre a un comando. Esto puede ser muy útil en comandos que
usemos frecuentemente y que tengan nombres largos, difíciles de recordar o con complicadas opciones.
Hay algunas diferencias de sintaxis dependiendo de la shell que empleemos (supondremos que usamos una
TC shell). Para definir los alias se usa el comando:
alias nombre definicion
Nombre es el nuevo nombre del comando (procurar que sea corto y fácil de recordar). Definición son los
comandos que queremos que se ejecuten cuando tecleamos el alias (es conveniente ponerlo entre ' ') por
ejemplo:
alias lf 'ls -F'
alias. 'echo $cwd; ls'
Si lo ejecutamos en la línea de comandos sólo tendrá validez en esa shell. Si queremos definirlo de forma
que quede permanentemente asignado lo debemos incluir en el fichero .tcshrc o cualquier otro fichero que
el .tcshrc ejecute. En la definición de los alias podemos no sólo hacer referencia a comandos sino también a
otros alias.
En el primer ejemplo definimos el comando lf que será equivalente al comando ls con la opción -F (esta
opción añade una / despues del nombre del fichero si es un directorio, un * si es un ejecutable, un @ si es
un link).
En el segundo ejemplo al teclear . nos mostrará el valor de la variable cwd que contiene el directorio en que
estamos y hace luego un listado de este directorio.
Pueden ponerse varios comandos en un mismo alias separandolos por ; asi como también está permitido la
utilización de pipes.
También se pueden pasar argumentos al alias desde la línea de comandos. Cuando ejecutamos un alias
podemos poner una serie de argumentos que se interpretan como si estuvieran inmediatamente después de
la definición del alias. Por ejemplo:
alias k9 'kill -9'
k9 17313
Al ejecutar esta última línea se matará el proceso 17313.
Si queremos que los argumentos que damos al alias se sitúen en un punto distinto del final, tenemos los
siguientes caracteres:
!^
!*
que deben estar precedidos de \ para evitar que el caracter ! sea interpretado por la shell de otra manera. El
primero pasa el argumento que aparece en primer lugar de la línea de comandos al punto donde aparece !^.
El segundo pasa todos los argumentos. Por ejemplo:
alias gv 'ghostview -a4 -swap -bg white \!^ &'
Tecleando gv file.ps podremos ver el fichero postscript file.ps con el programa ghostview. El argumento
que damos (que es el nombre del postscript) será introducido antes del caracter & que manda el proceso
al background.
Para ver todos los alias que hay definidos se ejecuta el comando alias sin argumento. Para ver la definición
de un alias concreto tecleamos alias name.
Para cancelar a definición de un alias se usa el comando unalias name. Si queremos cancelar la definición
definitivamente, tendremos que borrarlo del fichero .tcshrc.
Para evitar confusiones no se debe usar el nombre de un comando como alias para otro o el mismo
comando con diferentes opciones. Por ejemplo muchos usuarios suelen definir:
alias rm 'rm -i'
Al ejecutar rm * se ejecuta en realidad el comando rm -i * que nos va pidiendo confirmación de si queremos
borrar realmente los ficheros. El problema puede presentarse si nos abren una cuenta en otro sistema donde
no hayamos definido este alias y al ejecutar rm * nos borrara todos los ficheros sin pedir confirmación. Para
evitar esto es mejor definir el alias con otro nombre como del o rmi.
PERMISOS
Todos los ficheros en UNIX tienen un propietario y además están asociados a un grupo. Aunque un usuario
puede pertenecer a varios grupos, no puede estar trabajando simultáneamente en más de uno en la misma
shell. Los ficheros sólo pueden tener un grupo, que por lo general será el grupo en que el usuario estaba
trabajando en el momento de crearlo.
Los permisos se establecen para tres tipos de usuarios: el propietario, los miembros del grupo y el resto de
usuarios. Solamente el propietario puede modificar los permisos de un fichero.
Por otra parte todos los ficheros en UNIX tienen asociados tres tipos de permisos:
r Lectura
w Escritura
x Ejecución
Para poder verlos podemos usar el comando ls con la opción -l
-rw-r--r-- 1 fcabrera agn 23845 Oct 2 1997 text3
drwxr-xr-x 5 fcabrera agn 512 Feb 17 10:19 unix
El primer caracter de cada línea nos da información sobre el tipo de fichero. En este caso el primero sería un
fichero normal y el segundo un directorio.
Después hay nueve caracteres. Los tres primeros corresponden a los permisos del propietario del fichero,
que se indica en la tercera columna (fcabrera). Los tres siguientes corresponden a los permisos del grupo,
que se indica en la cuarta columna (agn). Los tres últimos corresponden a los permisos del resto de usuarios.
Los tres caracteres para el propietario, grupo u otros representan los permisos de lectura (r) escritura (w) y
ejecución (x) por este orden. Si se tiene permiso aparece la letra correspondiente y si no el signo -.
El significado de los permisos es diferente para ficheros y directorios:
Permiso Fichero Directorio
r Leer el ficheo Ver el nombre de los ficheros que contiene
w Escribir en el Crear, renombrar o borrar un fichero del dir.
x Ejecutar un programa Situarnos en él
o shell script Leer un fichero
Escribir en un fichero
Ejecutar un fichero.
Crear, renombrar o borrar un fichero del dir
Comandos relacionados con grupos
Antes de pasar a ver como se modifican los permisos es conveniente entender como funcionan los grupos y
algunos comandos relacionados con estos. En un sistema UNIX pueden haber definidos varios grupos. Para
ver cuales son estos grupos podemos usar el comando:
dispgid
Para ver a que grupo pertenecemos ejecutamos:
groups
y si queremos saber a que grupo pertenece otro usuario:
groups username
También podemos cambiar el grupo al que pertenece un fichero propio siempre que pertenezcamos al grupo
al que queramos cambiarlo.
chgrp group file
Cuando entramos en la cuenta estamos en un grupo por defecto. Si queremos cambiar a otro grupo al que
pertenezcamos usamos el comando:
newgrp group
Para volver al grupo anterior tecleamos:
exit
Si queremos saber en que grupo estamos trabajando en un determinado momento usamos el comando:
id
Modificación de permisos
Para cada fichero hay tres números, asociados a los permisos del propietario, grupo y otros. Este número se
obtiene sumando los valores asociados a los permisos que tenga el fichero. Estos valores son:
r w x
4 2 1
Así pues, un fichero con sólo permiso de lectura tendría el valor 4, lectura y escritura 6, etc.
Para dar los permisos que queramos a un fichero existe el comando chmod con el que asignamos un
número a los permisos de propietario, grupo y otros. Por ejemplo:
propietario grupo otros
chmod 640 file1 rw- r-- ---
chmod 754 file1 rwx r-x r--
chmod 664 file1 rw- rw- r--
Este comando puede usarse de otro modo sin hacer uso directamente de los números por ejemplo:
chmod go+rw filename
da permisos de lectura y escritura al grupo y otros (u, g, o representan propietario grupo y otros
respectivamente). Si utilizamos el signo menos quitamos estos permisos.
Se pueden modificar también los permisos que tienen por defecto los ficheros cuando se crean.
Normalmente un directorio se crea con permisos 777 y un fichero 666. El comando umask permite modificar
estos valores. Por ejemplo umask 022 significa que hay que restar este valor al que los permisos tienen por
defecto, es decir en este caso los permisos por defecto al crear directorios y ficheros serían respectivamente
755 y 644.
Para que se ejecute cada vez que entremos en una sesión podemos incluir el comando en el
fichero .cshrc (.tcshrc).
PROCESOS
Cada vez que introducimos un comando o un programa, la shell lo ejecuta. Mientras está en memoria
ejecutandose se le denomina proceso. Puede haber varios procesos ejecutando un mismo programa. Es
decir, existe una sola copia del programa en el file system y cada vez que se ejecuta se crea un proceso.
A cada proceso le corresponde un número llamado PID. Cuando se inicializa el sistema se crea un único
proceso perteneciente a root, que a su vez va a crear otros subprocesos en una estructura jerárquica.
También al entrar en nuestra cuenta ocurre lo mismo, se crea un proceso del que van a colgar una serie de
subprocesos. Cada proceso puede tener muchos subprocesos (child process) y un sólo proceso padre
(parent process).
Los procesos que nos pertenecen podemos manipularlos de diferentes formas. Al entrar un comando desde
una shell, ésta crea un child process donde se ejcutará el comando. La shell esperará a que se ejecute el
comando y cuando esto suceda podemos volver a ejecutar nuevos comandos. La ejecución de comandos de
esta manera se le denomina ejecución en el foreground y nos impide usar la shell mientras se ejecuta el
comando.
Existe sin embargo otra forma de ejecutar los comandos a la que se le denomina en el background. Para ello
se añade al final de la línea de comandos el caracter &. Al introducir el comando nos imprime en la terminal
dos números, el primero es el número del trabajo y el segundo el PID asociado al proceso.
Mientras se ejecutan los procesos en el background se puede seguir usando la shell. Si el proceso produce
alguna salida por la terminal, la podemos redireccionar para que no interfiera en lo que estemos tecleando en
la shell (también se puede redireccionar los errores). Por ejemplo:
du -k > file &
Los procesos que queramos ejecutar en el background no deben ser comandos que esperen a que
introduzcamos alguna información desde la shell interactivamente, pues en ese caso el proceso se parará.
Se puede solucionar redireccionando la standard input a un fichero que contenga exactamente lo que
teclearíamos en línea de comando
Los procesos que ejecutamos en el foregound podemos cancelarlos o también suspenderlos
momentaneamente para traerlos nuevamente al foreground o al background.
Para cancelar un proceso utilizamos CTRL-C y Para suspenderlo CTRL-X. Para mandar nuevamente
al foreground un proceso suspendido se usa fg, mientras para mandarlo al bacground se usa bg. Podemos
traer al foreground un proceso ejecutado en el background con el comando:
fg job_number
donde job_number es el número del trabajo, no el PID. Para ver el estado en que se encuentran los procesos
en el background utilizamos el comando jobs que nos dará el número y el estado de cada proceso en
el background. Con la opción -l también nos dará el PID.
Controlando los procesos
Hay varios comandos que permiten obtener información de los procesos que se están ejecutando. Los más
útiles son ps y top que veremos ahora con algo más de detalle.
ps
Nos da información sobre el estado de los procesos y tiene una gran variedad de opciones. Si lo ejecutamos
sin opciones nos muestra información sobre nuestros procesos asociados al terminal. La salida muestra el
PID, el terminal, el tiempo de CPU utilizado y el nombre del comando.
Con la opción -a se muestran los procesos que son requeridos más frecuentemente, y no sólo los procesos
asociados a un terminal. La opción -e muestra información de todos los procesos que se están ejecutando.
Para obtener información más detallada están las opciones -f y -l. Parte de la información que suministran es
la siguiente (se incluye entre parentesis a que opción corresponde):
UID (f,l) Nombre del usuario
PID (f,l) Número de identificación del proceso
PPID (f,l) Número de identificación del proceso padre
STIME (f) La hora de comienzo del proceso
TTY (f,l) El terminal
TIME (f,l) Tiempo de CPU
CMD (f,l) El nombre del comando
S (l) El estado del proceso
PRI (l) La prioridad del proceso
NI (l) El valor de nice para calcular la prioridad
ADDR (l) La dirección de memoria del proceso
SZ (l) La cantidad de memoria que esta ocupando
Los posibles estados de un proceso son:
 El proceso se está ejecutando en el procesador
 S (sleeping) El proceso está esperando por un suceso para terminar
 R (runnable) El proceso está en la cola de ejecución
 I Indica que el proceso está siendo creado
 Z (zombie) El proceso ha terminado y el proceso padre no está esperando
 T El proceso está parado por una señal del proceso padre
 X El proceso está esperando por más memoria
top
Nos muestra y actualiza periodicamente información sobre los procesos que más tiempo de CPU utilizan.
Además muestra información sobre el estado del sistema como: El último PID. Un promedio del número de
trabajos en la cola de ejecución. El número de procesos y cuantos se hayan en cada estado. El porcentaje
de tiempo que usa la CPU en diferentes estados. Información sobre la memoria del sistema.
La información de los procesos que se ofrece es:
PID
USERNAME
PRI
NICE
SIZE
RES
STATE
TIME
CPU
COMMAND
Con significados similares a los de ps. Las diferencias son SIZE y RES que representan el tamaño real del
proceso y la parte residente en memoria respectivamente. CPU es una estimacion del porcentaje de tiempo
de CPU usado.
Prioridades
La CPU tiene que compartir su tiempo entre los distintos procesos. El cálculo de la prioridad que tiene un
proceso lo hace el kernel y se basa en varios factores como el tiempo de CPU que ha usado recientemente,
el estado del proceso (si está esperando que introduzcamos un dato o está listo para ser ejecutado) y el valor
de nice del proceso.
Cada proceso tiene un valor de nice que varia entre -20 y 20. Cuanto más bajo mayor prioridad tendrá el
proceso.
Los procesos normalmente heredan de sus procesos padres la prioridad. Los usuarios sólo pueden tener
procesos con nice 0 o mayor, mientras que el super-user puede tener procesos con valores menores. Por
defecto los usuarios en la consola van a tener procesos con una prioridad de 0. Podemos lanzar procesos
con menor menor prioridad o bajar la prioridad de procesos que ya se están ejecutando, pero nunca
podremos aumentar la prioridad a un proceso, aunque previamente se la hubieramos bajado, sólo el super-
user puede hacer esto.
El valor de nice lo podemos ver con ps o top ( el primero nos lo muestra de 0 a 40 y el segundo de -20 a 20).
Para ejecutar un proceso con menor prioridad se usa el comando:
nice -n comando
n es el incremento que le damos al valor de nice y por tanto no podra ser mayor que 20. Si no damos valor
a n, se asume un valor de 4.
Para bajar la prioridad de un proceso se ejecuta el comando:
renice n PID
n es el valor de nice que vamos a dar al proceso que tendrá que ser mayor que el valor que tenga el
proceso. PID es el número identificador del proceso.
Hay varias razones para lanzar procesos con menor prioridad. La principal es que con ello se evita que un
proceso pueda acaparar el tiempo de la CPU haciendo que la máquina vaya muy lenta al trabajar de forma
interactiva. En la red del IAC, cuando ejecutamos procesos en una máquina en la que no estamos trabajando
en la consola, nice tendrá un valor de 10 para que el usuario que trabaja en consola tenga preferencia y
pueda trabajar interactivamente.
Matando procesos
Cuando queremos teminar un proceso tenemos varias formas de hacerlo. La más sencilla es utilizar CTRL-C,
si el proceso esta en el foreground.
Un proceso en el background podemos matarlo con el comando kill. Por ejemplo:
kill %2
mata el proceso que tiene como número de trabajo el 2 (no el PID).
Para matar un proceso cualquiera utilizamos:
kill PID
que tendría el mismo efecto que utilizar CTRL-C
Si esto no funciona podemos usar:
kill -1 PID
que tendría un efecto sobre el proceso igual a que si nos salimos de la cuenta, e intentará además matar
todos los subprocesos que cuelgan de él.
Si esto tampoco funciona se usa:
kill -9 PID
que matará el proceso (aunque es posible que queden subprocesos).
Lanzando procesos a determinadas horas
Es posible lanzar procesos de forma que se empiecen aejecutar a una determinada hora. Por ejemplo si
vamos a ejecutar procesos que van a utilizar mucho tiempo de CPU, es aconsejable hacerlo de forma que se
ejecuten por la noche, cuando normalmente habrá menos usuarios y evitaremos colapsar las máquinas. Es
posible hacerlo de forma que se ejecuten periodicamente o simplemente hacer una cola de comandos que se
van ejecutando secuencialmente cuando el nivel de carga del sistema lo permite.
Los comandos para hacer esto son at, batch y crontab.
at Nos permite especificar el momento en que queremos ejecutar los comandos. Si los procesos producen
una salida por pantalla o se producen errores nos envía un mail. Podemos especificar la hora con una gran
variedad de formatos. Algunos ejemplos que no requieren mayor explicación son:
at 0815am Jan 24
at 8:15am Jan 24
at now + 1 day
at now next day
at 5 pm Friday
Una vez introducido el comando, at nos cambia el prompt a:
at>
Entonces empezamos a teclear los comandos y cuando hayamos terminado salimos con CTRL-Z.
El comando batch es similar a at, sólo que no indicamos cuando ejecutar los comandos. Al ejecutar el
comando batch nos cambiará directamente al prompt at> donde tecleamos los comandos. Al salir con CTRL-
Z empezarán a ejecutarse los comandos.
crontab
Este comando sirve para crear, modificar o borrar un fichero donde cada usuario define una serie de
comandos que quiere que se ejecuten periodicamente o en determinadas fechas. Estos ficheros no están en
nuestro home o cualquier otro directorio que nos pertenezca, sino que estan en un directorio donde se
encuentran todos los crontabs de los usuarios del sistema. Las tablas dependen de la máquina, es decir un
usuario puede tener una tabla en cada máquina y cada máquina sólo ejecuta los comandos de la tabla
creada en ella.
Estas tablas tienen un formato definido. Son seis columnas separadas por espacios o Tab. La primera
columna corresponde a los minutos. La segunda corresponde a las horas. La tercera al dia del mes. La
cuarta al mes. La quinta al dia de la semana. La sexta el comando a ejecutar. Por ejemplo
#ejemplo de crontab
#min hora dia mes dia comando
#0-59 0-23 1-31 1-12 0-6
0 11,18 * * 1-5 cat sound.au>dev/audio
0 4 * * * cp -r /scratch/tesis /scratch2
Los comandos se ejecutarán cuando la hora y fecha coincida con las indicadas en la tabla. En cada columna
pueden indicarse varios valores separados por comas, dar rangos con números separados por el signo
menos, o pueden tener un asterisco que indica cualquier valor. Los dias pueden indicarse por el dia del mes
o de la semana, si se indican valores para los dos el comando se ejecutará cuando se cumpla que la fecha
coincida con cualquiera de los dos (por ejemplo indicar que se ejecute el primero de mes y todos los
sabados). Si queremos definir el dia bien por el mes o bien por la semana, ponemos un asterisco en el que
no vamos a utilizar.
El comando crontab tiene varias opciones:
crontab filename
Copia el fichero filename como la tabla crontab. Las modificaciones que hagamos en filename no tendrán
efecto hasta que no ejecutemos el comando.
crontab -e
Permite editar la crontab que tengamos definida.
crontab -l
Permite ver la crontab que tengamos definida.
crontab -r
Borra la crontab.
DISPOSITIVOS EXTERNOS
En esta sección se explicarán algunos comandos para utilizar varios de los dispositivos conectados al
sistema que se usan más frecuentemente (impresoras, dispositivos magnéticos, floppies).
Impresoras
Los comandos básicos para controlar las impresoras son lp, lpstat, cancel.
lp
Envía a la impresora un fichero. Si no indicamos a que impresora lo enviamos, la máquina selecciona la que
tiene definida que será la más cercana. Podemos cambiar la impresora que tenemos por defecto con la
variable PRINTER. Por ejemplo incluyendo en el .login
setenv PRINTER lw1
Si queremos enviar un fichero a otra impresora usamos la opción -d
lp -d lw3 file1
Se pueden enviar varios ficheros simultáneamente:
lp file1 file2 file3 ....
Podemos también usar pipes:
man ls | lp
Al enviar el fichero nos mostrará el nombre del trabajo de impresora.
lpstat
Nos permite ver cual es el estado de los trabajos de impresión que hemos enviado. Tiene también varias
opciones que nos permiten ver el estado de la impresora.
cancel
Nos permite cancelar un trabajo que hayamos enviado a impresora y todavía esté en la cola de impresión.
Tenemos que conocer el nombre del trabajo (podemos verlo con lpstat). La sintaxis es:
cancel nombre_trabajo
Dispositivos magnéticos
En el IAC existen dos tipos de dispositivos magnéticos: DATs y exabytes. Estos dispositivos se usan para
guardar grandes cantidades de datos a los que no vamos a acceder con frecuencia y para hacer copias de
seguridad (backups).
La capacidad de los dats es aproximadamente 2GB sin compresión que puede llegar a ser hasta 4GB con
compresión. Todos los DATs usan la compresión al escribir, y al leer pueden hacerlo con o sin compresión,
según hayan sido grabados.
Los exabytes ofrecen una mayor capacidad de almacenamiento de datos aunque son algo más lentos.
Dependiendo de la densidad y de si usan compresión o no, su capacidad puede variar entre 2 y 10GB.
Los comandos para utilizar los dispositivos magnéticos son mt y tar.
mt
Este comando permite controlar los dispositivos magénticos. Para ello envía diferentes comandos a los
dispositivos. Si no especificamos a que dispositivo, utilizará el que haya definido en la variable de entorno
TAPE. La sintaxis básica del comando es:
mt [ -f tapename ] command [ n ]
Algunos de los comandos que podemos enviar al dispositivo magnético son:
eof, weof Escribe n marcas de final de fichero (EOF) en la posición actual.
fsf Avanza n marcas de EOF y se posiciona en el primer bloque del siguiente fichero.
bsf Retrocede n marcas de EOF y se posiciona al principio de la marca de EOF.
nbsf Retrocede n ficheros. Es equivalente a bsf n+1 seguido de fsf 1.
asf Equivalente a rebobinar y luego fsf n.
eom Se sitúa al final de la parte grabada de la cinta.
rewind Rebobina la cinta hasta el principio.
offline Saca la cinta del dispositivo.
status Da información del estado del dispositivo.
erase Borra la cinta.
Las marcas de EOF, son marcas que se graban cada vez que escribimos un fichero en la cinta.
tar
Este comando sirve para crear tarfiles, que son ficheros que se pueden almacenar en cinta (estos ficheros
pueden guardarse también en disco). Además el comando permite guardar y extraer ficheros de
estos tarfiles.
Cuando grabamos los ficheros en cinta no los hacemos uno a uno sino que son agrupados en los tarfiles que
son los que se graban en la cinta (o en cualquier otra parte del sistema de ficheros a la que tengamos acceso
y en este caso generalmente se les pone la extensión .tar al nombre del fichero).
tar Tiene cinco argumentos clave (c, r, t, u, x) que realizan las siguientes acciones:
c Crea un nuevo tarfile.
r Escribe ficheros al final del tarfile.
t Permite ver que ficheros contiene el tarfile. Con la opción -v ofrece más información similar a un ls -l.
u Actualiza los ficheros del tarfile que han sido modificados o los que han sido creados después de la última
actualización del tarfile.
x Extrae ficheros del tarfile.
Además de estos cinco argumentos hay otras opciones importantes:
f Indica el nombre del dispositivo o del fichero tar que se va a crear.
v Da información por la terminal de los ficheros con que está trabajando.
m No extrae los tiempos en que fueron modificados los ficheros, sino que el tiempo de la última modificación será el
de la extracción. h Sigue los link simbólicos a otros directorios o ficheros.
Veamos algunos ejemplos sencillos:
tar tvf /dev/rmt/3bn
Nos muestra los ficheros que hay en la cinta del dispositivo /dev/rmt/3bn. Sólo nos mostrará el
primer tarfile que haya en la cinta. Si hay más ficheros grabados tenemos que mover la cinta al
siguiente tarfile y volver a ejecutar el comando.
tar cvf /dev/rmt/4bn .
Crea un tarfile en la cinta del dispositivo /dev/rmt/4bn, donde se archivarán todos los ficheros en el directorio
en que estemos y todos los subdirectorios que cuelguen de él.
tar xvf tesis.tar
Extrae los ficheros del tarfile tesis.tar y los pone en el directorio en que estamos.
tar uvf /dev/rmt/1bn .
Graba al final del tarfile los nuevos ficheros del directorio y los que han sido modificados depués de la última
versión que contiene el tarfile de los ficheros. Si se trata de una cinta hay que tener la precaución de que no
haya nada grabado después, ya que se borraría al aumentar el tamaño del tarfile.
Hay varias precauciones a tener en cuenta al hacer un backup de un disco. Los ficheros que se van incluir
deben darse con una ruta de acceso relativa, no la ruta de acceso completa. Si no lo hacemos, cuando
queramos recuperar los ficheros con tar, tratará de crearlos exactamente con la misma ruta de acceso
cuando posiblemente queremos utilizar otro disco o estamos en otro sistema donde no existen los directorios
que se guardaron en la cinta.
No se van a copiar directorios vacios, ni ficheros de los que no tengamos permisos de lectura aunque sean
nuestros. Normalmente tampoco se siguen los links simbólicos.
Nombres de los dispositivos
Para ver la lista de los dispositivos magnéticos disponibles en el IAC podemos mirar las páginas Web del
centro de cálculo. Los nombres de los dispositivos magnéticos conectados a una máquina empiezan
por /dev/rmt/. Depués viene un número que corresponde al dispositivo que vamos a usar. Luego hay varias
opciones, si el dispositivo admite que le indiquemos la densidad, va una letra (l baja, m media, h alta, u ultra,
c compresión). Depués añadimos una b, de no hacerlo una sola marca EOF indicaría el final de la cinta.
Luego podemos añadir una n que evita que se rebobine la cinta después de cualquier operación. Así pues,
un dispositivo DAT tendrá típicamente por nombre algo similar a /dev/rmt/2bn.
Floppies
Los floppy disks pueden ser montados, en las máquinas que tengán instalado el dispositivo para leerlo, de
forma sencilla. En general lo más fácil es emplear alguna utilidad como filemanager para montarlos, pero
puede accederse a ellos también desde la shell.
El floppy quedará montado en el directorio /floppy, que estará vacio antes de que lo montemos. Lo primero
es introducir el floppy en el dispositivo. Si nos situamos en /floppy y ejecutamos ls veremos que sigue vacio.
Para que se reconozca el disco tenemos que usar el comando volcheck, que examinará si hay
algún floppy en el dispositivo. Una vez hecho esto ya aparecerá un subdirectorio en /floppy, asociado
al floppy y al que podemos acceder.
Si necesitamos formatear el floppy ejecutamos fdformat.
Para sacar el floppy del dispositivo en muchas ocasiones hay que hacerlo por software, pues exepto los
ultimos modelos, las estaciones de SUN no tienen un botón para sacarlo manualmente. El comando para
hacerlo es eject.
UTILIDADES PARA TRABAJAR EN RED
ftp
El comando ftp es una interface para que el usuario acceda al File Transfer Protocol, que permite transferir
ficheros entre sistemas remotos.
El comando se usa con la siguiente sintaxis:
ftp
ftp hostaname
En el primer caso nos cambia el prompt a ftp> y accedemos a una serie de comandos que son del ftp. Estos
comandos, aunque en muchos casos coinciden con los de UNIX, no son comandos de UNIX y realizan
funciones diferentes.
En el segundo caso entramos en ftp y nos conectamos directamente a otra máquina que generalmente no
será una máquina local.
Los comandos propios de ftp son:
! cr macdef proxy send
$ delete mdelete sendport status
account debug mdir put struct
append dir mget pwd sunique
ascii disconnect mkdir quit tenex
bell form mls quote trace
binary get mode recv type
bye glob mput remotehelp user
case hash nmap rename verbose
cd help ntrans reset ?
cdup lcd open rmdir
close ls prompt runique
Para saber lo que hace un comando tecleamos help comand_name (no se usa el comando man).
Los comandos que más se usan con ftp son los siguientes:
open
Si entramos en ftp sin indicar a que máquina nos queremos conectar, podemos abrir posteriormente una
conexión con este comando. Por ejemplo:
open ned.ipac.caltech.edu
close
Cierra la conexión que tengamos abierta.
ls
Nos hace un listado del directorio remoto, es decir del directorio en que nos hemos situado en la máquina a
la que nos conectamos.
cd
Cambia de directorio en la máquina remota.
mkdir y rmdir
Respectivamente crean y borran un directorio en la máquina remota
get, put, mget, mput
Son unos de los comandos más usados. get y mget sirven par copiar un fichero de la máquina remota a la
local. mget permite traer varios ficheros de una sola vez. put y mput son similares pero copian los ficheros de
la máquina local a la remota. Veamos algunos ejemplos:
get file1
mget *
mput l1 l2 l3
El primero nos traerá el fichero l1. El segundo nos traerá todos los ficheros. El tercero nos pondrá en la
máquina remota los ficheros locales l1 y l2.
prompt
Ejecutando prompt off, desactivamos el modo interactivo que nos pregunta por cada fichero al
utilizar mget o mput.
lcd
Cambia el directorio en la máquina local.
delete y rename
Respectivamente borran y renombran ficheros en la máquina remota.
!
Ejecuta un comando UNIX en la shell local. Por ejemplo:
!ls
hace un listado del directorio en que estamos de la máquina local
ascii y bin
Son dos modos de transferencia de datos. ascii se utiliza solamente para ficheros con contenido de texto en
formato ASCII. bin se utiliza para ficheros en formato binario (imágenes, ejecutables, etc).
bye
Cierra la conexión y sale de ftp.
Servidores de ftp
Normalmente la mayor parte de centros de investigación, universidades, empresas comerciales, etc, que
tengan una red local, van a tener un servidor de ftp al que podemos conectarnos para traer y dejar ficheros,
aunque con ciertas restricciones.
Al conectarnos por ftp a una máquina externa, nos va a pedir un login y un password. Si tenemos una cuenta
en esa máquina podemos darle nuestro username y nuestro password. Sin embargo lo más usual es utilizar
el ftp anonimo, si el sistema en cuestión ofrece este servicio. Cuando nos pide
el login introducimos anonymous y en el password damos nuestra dirección completa de mail. Con esto no
entraremos realmente en el sistema sino en un área restringida en la que sólo vamos a poder acceder a una
serie de directorios. También suele haber diferentes restricciones sobre la posibilidad de dejar ficheros o
sobre el tiempo que éstos permanecen sin ser borrados.
El uso del servidor de ftp del IAC está descrito en detalle en las páginas del centro de cálculo. Las
características más importantes son:
El nombre es ftp.ll.iac.es
Los usuarios del IAC entran con el login iac y con el password iac.
Los usuarios externos entran con login ftp y como password la dirección de mail
Hay limitaciones en cuanto a espacio (un máximo de 4.5GB) y en cuanto a tiempo (un máximo de 10 dias).

Uso eficiente de ftp


Para que la transferencia de ficheros sea rápida es conveniente preparar los ficheros para la transmisión.
El primer paso es agrupar los ficheros. Si queremos transferir toda una estructura de directorios lo mejor es
crear un tarfile de disco. Por ejemplo:
tar -cvf file.tar .
Una vez tenemos el file.tar podemos reducir su tamaño comprimiendolo. De esta forma ahorraremos tiempo
en la transmisión. Los comandos más usados para comprimir ficheros son compress y gzip. Por ejemplo:
compress file.tar
gzip file.tar
Los dos comprimen el fichero. En el primer caso añade al nombre del fichero la extensión .Z y en el segundo
la extensión .gz. Para descomprimirlo usaríamos:
uncompress file.tar
gunzip file.tar
No hace falta indicar la extensión.
Por último se puede dar un paso más que es codificar el fichero comprimido para que pueda ser transmitido
en formato ASCII (esto permitiría además enviarlo por mail como un fichero de texto). Los comando
son uuencode y uudecode para codificar y decodificar respectivamente.
uuencode file.tar.Z file.tar.Z > file.tar.uu
uudecode file.tar.uu
El primero codifica file.tar.Z (primer argumento) indicando que al decodificar el fichero se
llamará file.tar.Z (segundo argumento que podría ser otro nombre) y es direccionado al fichero file.tar.uu. El
segundo comando decodifica creando un fichero cuyo el nombre es el del segundo argumento utilizado
en uuencode.
rlogin y telnet
Estos dos comandos nos permiten conectarnos a otra máquina y trabajar en ella, siempre que tengamos
cuenta en esa otra máquina. Normalmente se usará telnet para conectarnos a máquinas externas
mientras rlogin se usa para conectarnos a una máquina local. En ambos casos la sintaxis es el comando
seguido del nombre de la máquina.
Al ejecutar telnet a una máquina remota nos pedirá el login y el password. Le daremos el username y
el password correspondiente a la cuenta que tengamos en la máquina remota. Una vez hecho esto ya
entramos en la cuenta remota donde se ejecuta su .cshrc y .login correspondiente y podremos empezar a
trabajar.
Uno de los usos que probablemente hagamos con mayor frecuencia de telnet es para conectarnos a la red
del IAC desde fuera. Por razones de seguridad hay una serie de restricciones para las conexiones desde el
exterior. No podremos hacerlo con nuestra cuenta sino cou una cuenta temporal (cuenta externa) que
tendremos que pedir al administrador del sistema (ver páginas del centro de cálculo). Con esta cuenta (que
tiene un login un y password distinto al de nuestra cuenta en el IAC) sólo podemos entrar a la
máquina sal con el comando telnet sal.ll.iac.es. Desde sal ya podemos conectarnos a cualquier otra
máquina del IAC. Para llevarnos ficheros de nuestra cuenta desde una cuenta externa tenemos dos
opciones: 1) Entrar en una máquina del IAC y desde alli hacer un ftp al servidor de ftp de la máquina desde
la que estamos trabajando. 2) Si en la máquina donde trabajamos no está permitido que un usuario externo
deje ficheros, tenemos otra opción. Primero entramos en una máquina del IAC. Después ponemos en el
servidor de ftp del IAC nuestros ficheros y por último hacemos un ftp desde la máquina en que estamos al
servidor de ftp del IAC y copiamos los ficheros.
El comando rlogin lo utilizaremos para conectarnos a una máquina de la red local. Al hacer un rlogin a otra
máquina del IAC no nos va a pedir el password, a no ser que queramos entrar como otro usuario (por
ejemplo si tenemos dos cuentas). En este caso usamos la opción -l. La sintaxis sería:
rlogin -l username host
username es el nombre de la cuenta en que queremos entrar y host la máquina. Con esta opción nos pedirá
el password.
No es necesario entar en una máquina para ver un disco conectado a la máquina remota. Estos discos se
pueden ver a través de el directorio net. por ejemplo el disco lisa1 de la máquina lisa lo podemos ver desde
cualquier otra máquina como /net/lisa/lisa1. La razón principal para conectarnos a otra máquina será porque
necesitemos ejecutar procesos en una máquina más potente o con más memoria.
Para salirnos de una conexión remota bien con telnet o con rlogin ejecutamos el comando exit o logout.
rsh
Este comando nos permite ejecutar un proceso en otra máquina sin necesidad de entrar en ella con rlogin.
La standard input, la standard output y la estandard error siguen siendo la terminal de la máquina local. Por
ejemplo:
rsh lisa last -10
Ejecutará en la máquina lisa el comando last-10. Este comando con esta opción nos escribe en la terminal
los 10 últimos usuarios que se han conectado a la máquina (en este caso la máquina remota lisa), aunque
ya no estén conectados.
rcp
Este comando sirve para copiar ficheros que están en una máquina y no son visibles desde otra. Aunque
podemos trabajar con la mayor parte de los discos de cualquier máquina sin necesidad de conectarnos a
ella, pueden darse algunos casos en que no tengamos acceso a algún fichero de una máquina determinada.
Por ejemplo, en el caso que tengamos que leer un disco floppy en una máquina distinta a la que estamos
trabajando. No podremos acceder a el floppy si no nos conectamos con rlogin a la máquina. Sin embargo si
podríamos copiar los ficheros desde nuestra máquina ejecutando:
rcp host:/floppy/..../* .
host es el nombre de la máquina le siguen : y la ruta de acceso a los ficheros a copiar. Por último el . indica
que lo copie al directorio en que estamos.
talk
Este comando nos permite comunicarnos con otro usuario en otra terminal. El texto que escribamos en
nuestra terminal aparecerá también en una terminal del usuario con quien queremos hablar, y lo que el otro
usuario escriba en su terminal aparecerá en la nuestra. La sintaxis es:
talk username [terminal]
talk username@host [terminal]
La primera opción es para un usuario que este en la misma máquina y la segunda para un usuario en una
máquina remota. El terminal es opcional y se usa para especificar en cual queremos que aparezca el texto
en caso del que el usuario este en más de una. Por ejemplo:
talk fcabrera@lisa pts/7
Intentará conectar con el usuario fcabrera en la máquina lisa en el terminal pts/7, y aparecerá en el
terminal pts/7 un mensaje que le indica a fcabrera que responda con talk al usuario que ejecuto el
comando.
write
Este comando permite escribir un mensaje en un terminal de otro usuario que este conectado a la misma
máquina. La sintaxis es:
write username [terminal]
Donde terminal es opcional y sirve para indicar en que terminal queremos que aparezca el mensaje en el
caso de que este conectado desde varias. El terminal del usuario al que enviamos el mensaje le avisará que
va aparecer por su terminal un mensaje y quien y desde que máquina se lo envía. Lo que se teclee en la
terminal del que envía el mensaje aparecerá en la terminal del que lo recibe. Por ejemplo:
write fcabrera pts/7
Le avisará a fcabrera que va aparecer un mensaje en el terminal pts/7 enviado por la persona que ejecuta el
comando.
mail
mail es el comando para enviar y leer correo electrónico desde la shell. Normalmente el correo electrónico lo
vamos a enviar o leer con algún programa que nos permita hacerlo de forma más sencilla como puede ser
el mailtool o desde netscape. Sin embargo es conveniente conocer algún programa que permita hacerlo
desde la shell, pues no siempre vamos a poder abrir ventanas y tendremos que leerlo desde una terminal de
texto. Es por ejemplo el caso que se presenta cuando queremos leer el mail desde fuera del IAC con una
cuenta externa (esta conexión no permite abrir ventanas). Hay varios comandos que permiten leer
el mail desde la shell. Los más usados son mail, mailx, y pine.
El comando mail es el más básico y suele estar instalado en todos los sistemas. (es el que se va describir a
continuación). En mailx se ofrecen más facilidades y opciones al usuario y es similar a mail (puede
considerarse como una versión más avanzada). El programa pine nos permite interactuar con él a través de
un sistema de menus. En cualquier caso una vez aprendido el funcionamiento de mail es muy fcáil utilizar
cualquiera de los otros.
El comando mail funciona en dos modos: para enviar y para recibir, que a continuación se describen.
Enviar mensajes con mail
La sintaxis del comando puede tener las siguientes formas:
mail usuario1 usuario2 usuario3 ....
mail usuario1 usuario2 .... < file
En la primera opción enviaremos un mensaje que escribimos en la terminal. Puede ser enviado a uno o
varios usuarios. La forma de indicar el usuario al que va dirigido es con el username si es un usuario local
y username@system_name si es a un usuario de otro sistema. Por ejemplo si alguien quiere enviarme
un mail desde fuera del IAC tendrá que poner:
mail fcabrera@iac.es
Una vez tecleado el comando, esperará a que introduzcamos el texto. Si queremos introducir
un subject ponemos en la primera línea:
Subject: texto_del_subjet
Luego escribimos el texto del mail. Para terminar y que lo envíe ponemos al principio de una línea el
caracter . y pulsamos return.
En el segundo ejemplo no introducimos por teclado el texto sino que previamente lo hemos editado en un
fichero que se tomará como la standard input.
Si queremos enviar un fichero en formato binario, tenemos que pasarlo previamente a formato ASCII con el
comando uuencode como se explicó anteriormente.
Leer mensajes con mail
Para ejecutar el comando mail en modo de recibir, tecleamos mail sin argumentos. El prompt nos cambiara
a ? y ahi podremos teclear una serie de comandos propios de mail. Se indican a continuación los más útiles:
? Muestra una ayuda sobre los comandos
# Nos muestra el número del mensaje que estamos viendo
- Muestra el mensaje anterior
+ Muestra el mensaje siguiente
! cmd Ejecuta un comando en la shell
a Nos sitúa en el último mensaje y nos dice si hay nuevos mensajes
d [#] Borra un mensaje (por defecto en el que estamos)
ha Muestra todas las cabeceras
hd Muestra las cabeceras de los mensajes seleccionados para borrar
h [#] Muestra las cabeceras de los mensajes cercanos al actual
m user Envía uno de los mensajes a un usuario y lo borra
p Muestra un mensaje que tiene algun contenido binario que normalmente no se muestra
P Muestra la cabecera completa
q, ^D Sale del programa
r [args] Responde un mail y lo puede enviar a otros usuarios[args]
s [files] Mueve un mensaje a un fichero (por defecto a mbox)
u [#] Recupera un mensaje borrado
w [files] Guarda un mensaje en un fichero sin la cabecera
x Sale del programa ignorando los cambios que hayamos hecho

(El caracter # representa el numero de un mensaje)


Los mails que recibimos se guardan en el directorio /var/mail/, donde cada usuario tiene un fichero donde se
almacenan. Cuando los leemos debemos ir pasandolos a directorios propios para no ocupar demasiado
espacio en este directorio común. Cuando los gravamos a los ficheros nuestros, no se borrarán realmente
de /var/mail hasta que salgamos del programa mail con una opción que realize los cambios, como q. Si
salimos con la opción x no se realizarán los cambios que hayamos hecho, es decir los mails que hayamos
borrado seguirán estando. Otros lectores de mail tienen también opciones parecidas.
Listas de mail
Existen en todos los sistemas unas listas de mail, que pueden ser definidas por el administrador del sistema.
Estas listas permiten comunicarse entre si a los usuarios que pertenecen a estas listas. Al enviar
un mail dirigido a la lista se enviará a todos los usuarios de ésta.
Para ver que listas hay definidas y quien pertenece a ellas podemos enviar
un mail a majordomo. Majordomo es un sistema automático que nos permite subscribirnos o borrarnos de
una lista pedir información sobre ella etc. Para utilizarlo envía un mail sin subject a majordomo y ponemos un
comando en el texto que puede ser para subscribirnos a una lista, para pedir ayuda, etc. Majordomo nos
contestará con un mail donde nos informa de los resultados del comando enviado. Por ejemplo, si enviamos
un mail con el comando help nos devuelve un mail con información de como funciona majordomo y los
comandos que podemos enviar. Enviando el comando lists nos devuelve un mail con las listas que están
definidas.
SHELL SCRIPTS
Como se vió al principio del curso, la shell nos permite acceder al kernel del sistema operativo. La shell en
reaildad lo que hace es interpretar la línea de comandos y ejecutar los programas que ésta indica. Sin
embargo, además de leer la línea de comandos, también puede ejecutar los comandos que se encuentren en
un fichero. Cualquier comando que pueda ser tecleado en la línea de comandos puede ser incluido en un
fichero al que se le denomina como shell script o shell program.
Un shell script es un fichero donde hemos introducido cualquier comando que se puede ejecutar en la shell.
Se pueden incluir comandos UNIX, utilidades, emplear pipes, redireccionar entradas y salidas, definir y
utilizar variables, además del uso de una serie de comandos UNIX creados para ser usados
fundamentalmente en los shell scripts, como son condicionales y comandos para controlar el flujo del
programa.
Estos comandos UNIX especificos de los shell scripts, suelen tener una sintaxis distinta dependiendo de la
shell empleada. Hay dos opciones básicas que tienen a su vez algunas diferencias. Por un lado están la Korn
shell y la Bourne Again shell, que tienen un lenguaje similar al de la shell original de UNIX (Bourne shell). Por
otro lado están la C shell y la TC shell que son muy similares entre si (en el curso utilizaré esta opción
aunque cada vez es más frecuente utilizar la Korn shell).
Vamos a empezar con un ejemplo muy sencillo. Creamos un fichero que se llame INFO y escribimos en el
los siguientes comandos:
# Script que nos muestra por pantalla la fecha, la hora, la maquina en que
# estamos, nuestro username, nuestro numero identificador de usuario y de
# grupo, quien esta conectado a la maquina y el directorio en que estamos
echo "la fecha de hoy es `date`"
echo "La maquina en que estas trabajando es: $HOST"
echo ""
echo -n "Tu user name es: "
whoami
echo "Los numeros identificadores de usuario y de grupo son:"
id
echo ""
echo "En la maquina estan conectadas las siguientes personas "
who
echo "Estas en el directorio `pwd`"
Luego ponemos el fichero en un directorio al que haga referencia la variable PATH. Normalmente los
usuarios tienen definido el directorio bin, donde ponen sus ejecutables y al que hace referncia la variable
PATH. Finalmente le damos permiso de ejecuión al fichero.
chmod a+x INFO
Ahora podemos teclear en la línea de comandos desde cualquier directorio
INFO
y se ejecutarán los comandos incluidos en el fichero.
Este es un sencillo ejemplo de shell script en que simplemente se ejecutan una serie de comandos
secuencialmente. Sin embargo las posibilidades que permite la programación en shell son mucho más
amplias.
El script INFO sólo usa comandos estandard de UNIX que funcionan en cualquier shell. Si vamos a crear
un shell script que usa características especificas de una shell en concreto, tenemos que indicar al principio
del script en que shell queremos que se ejecute. Para ello se pone en la primera línea del script los
caracteres #! seguido de la ruta de acceso al fichero ejecutable que corresponde a la shell. Por ejemplo para
especificar que el script se ejecute en una C shell pondremos en la primera línea:
#!/bin/csh
donde /bin/csh es la ruta de acceso al programa que ejecuta una nueva C shell. De esta forma el fichero
ejecuta una C shell y los comandos que van acontinuación se ejecutan como subprocesos de esta C shell.
Argumentos, Variables y condicionales
Argumentos de los shell scripts
Los scripts pueden ejecutarse con argumentos introducidos desde la línea de comandos. Para utilizar un
determinado argumento en el shell script nos referimos a el con $ seguido de un número que indica la
posición en la línea de comandos en que fué introducido. Veamos el siguiente ejemplo:
#!/bin/csh
#Ejemplo para ver como se pasan argumentos a un shell script
#Imprime los argumentos en orden inverso (hasta un maximo de 9)
echo "los argumentos introducidos son : $9 $8 $7 $6 $5 $4 $3 $2 $1"
Variables en los shell scripts
Dentro de los shell scripts podemos usar el comando set para definir las variables de la misma forma que se
hace en la línea de comandos. Veamoslo ahora con más detalle.
set varname=value
set varname[n]=word
value puede ser una palabra (o una cadena cualquiera de caracteres entre comillas), o puede ser una serie
de palabras separadas por espacios, en cuyo caso hay que ponerlas entre parentesis). De esta forma se
definen variables con indice. Para asignar un valor a un sólo indice se utiliza el segundo formato.
Las variables de la shell utilizada en el script también están definidas y podemos utilizarlas. Además hay una
serie de variables con significados especiales que son muy útiles para crear shell scripts, por ejemplo:
 argv Contiene una copia de los argumentos de la linea de comandos. Es una variable con indices de
forma que a traves de ellos podemos referirnos a los argumentos introducidos (es decir para
referirnos al argumento 2 podemos usar $2 o $argv[2]).
 El símbolo # precediendo una variable nos da el número de palabras de esa variable ($#argv es el
número de argumentos introducidos).
 $0 Contiene el nombre del fichero que está siendo ejecutado (el shell script).
 El caracter ? precediendo a una variable tendrá por valor 1 si la varible está definida y 0 si no lo está.
 $$ Sirve para referirnos al numero de proceso del shell script
 $< Nos permite leer una línea de la standard input. Puede ser usada para leer datos introducidos por
el teclado.
Para aclarar todo esto veamoslo con el siguiente ejemplo en el que creo el script ejemp2 que simplemente
muestra una serie de variables.
#!/bin/csh
#Ejemplo para ver como se definen las variables y
#mostrar algunas variables especiales
text1="Esta variable tiene solo un indice"
echo "El numero de indices de la variable text1 es $#text1 y su valor es:"
echo $text1
echo ""
text2=(Esta variable tiene varios indices)
echo "El numero de indices de la variable text2 es $#text2 y sus valores son:" echo $text2[*]
echo ""
echo "Has tecleado $#argv argumentos que son: $argv"
echo ""
echo "El valor de la variable path es:"
echo $path
echo "" echo "La shell en que se ejecutan los comandos del script es $shell" echo "El PID de este script es $$ y el
nombre del comando $0"
echo ""
echo "Teclea una linea en la terminal"
echo "Has tecleado: $<"

El resultado de ejecutar este ejemplo introduciendo como argumentos:


abcd
y tecleando al final del programa:
Esto es solo un ejemplo
es el siguiente:
El numero de indices de la variable text1 es 1 y su valor es:
Esta variable tiene solo un indice

El numero de indices de la variable text2 es 5 y sus valores son:


Esta variable tiene varios indices

Has tecleado 4 argumentos que son: a b c d

El valor de la variable path es:


/home/fcabrera/bin /usr/bin /usr/sbin /usr/ccs/bin /usr/dt/bin /usr/openwin/bin /opt/local/bin
/opt/SUNWspro/bin /usr/ucb /usr/local/bin /usr/X11/bin /opt/hpnp/bin .
/usr/SUNWwabi/bin /opt/gnu/bin /usr/gipsy/exe/sol4 /net/lisa/lisa3/fcabrera/l3/c84/ /net/lisa/lisa3/fcabrera/c90

La shell en que se ejecutan los comandos del script es /bin/csh


El PID de este script es 29897 y el nombre del comando ejemp2
Teclea una linea en la terminal Esto es solo un ejemplo
Has tecleado: Esto es solo un ejemplo
Expresiones aritméticas
La shell nos permite definir variables con valores númericos y realizar determinadas operaciones aritméticas
que puden ser muy útiles en los shell scripts. La sintaxis para definirlas es:
@ variable = valor
Los operadores que podemos usar son:
+ Suma
- Resta
* Multiplica
/ Divide (parte entera)
% Resto de una división

Por ejemplo el comando:


@ res = $var1 + 3
Sumará 3 a la variable var1 y se lo asigna a la variable res. También tienen validez para la shell los
operadores ++ y -- que suman y restan 1 respectivamente a una variable. Por ejemplo:
@ res ++
Sumará uno a la variable res.
Condicionales
Puede utilizarse el comando if para ejecutar comandos según se cumpla o no una condición. La estructura
de un comando if es:
if (expr) then
...
else if (expr2) then
...
else
...
endif
Veamos un ejemplo sencillo:
#Ejemplo para mostrar el funcionamiento de if
#Comprueba si existe un fichero en el directorio, si esta nos ejecuta ls -l
#Si no esta nos dice "no existe un fichero con el nomgre ..."
ls $1>/dev/null
if ($status != 0) then
echo "No existe el fichero $1"
else
ls -l $1
endif
Primero se hace un ls del fichero buscado, enviando la salida al dispositivo /dev/null porque no nos interesa.
Luego comprueba si el valor de la variable status es distinto de 0. Esta variable se define automáticamente y
su valor depende de si el comando anterior (ls) tiene exito, en cuyo caso tendrá un valor de 0, o da algún
error, en cuyo caso su valor será distinto de 0. Así pues, si el fichero existe status valdra 0 y se ejecuta ls -
l y si el fichero no existe, status tendrá otro valor y se ejecuta echo "No existe el fichero $1".
Los operadores lógicos y de comparación que se pueden usar en las expresiones son:
OPERADORES LOGICOS
! NOT
&& AND
|| OR

OPERADORES DE COMPARACION
== Igual (enteros o cadenas de caracteres)
!= Distinto (enteros o cadenas)
=~ La cadena de la izquierda se ajusta al patrón de la derecha
!~ La cadena de la izquierda no se ajusta al patrón de la derecha
> Mayor que (enteros)
< Menor que (enteros)
>= Mayor o igual (enteros)
<= Menor o igual (enteros)

Además se pueden usar los paréntesis.


Comandos mas importantes
El comando foreach
Su estructura es la siguiente:
foreach var (wordlist)
...
end
La variable va tomando cada uno de los valores de la lista y para cada valor se ejecutan los comandos
comprendidos entre foreach y end. Veamos un ejemplo:
#!/bin/csh
#Ejemplo para mostrar el funcionamiento de foreach
#Cambia de minuscula a mayuscula el contenido de los ficheros
#que se introducen como argumentos en la linea de comandos escribiendolos
# en un fichero con el mismo nombre y extension.M
foreach f ($argv[*])
set name=$f.M
cat $f | tr 'a-z' 'A-Z' > $name
end
La variable f va tomando cada vez el nombre de uno de los argumentos. Se define luego la
variable name que será igual al nombre de entrada con la extensión .M. El comando cat envía el contenido
de cada uno de los ficheros de entrada al comando tr (que es el que transforma las minúsculas en
mayúsculas) y este envía la salida a el fichero con el mismo nombre y extensión .M.
Vamos a ver un ejemplo de un shell script algo más elaborado que combina foreach e if. El script se ejecuta
como:
mata host
Donde host es el nombre de una máquina. El script buscará los PID de todos los procesos que tengamos en
esa máquina y los matará con kill -9. El contenido del script mata será:

#!/bin/csh
#Script que mata todos los procesos que tengamos corriendo en una maquina
#La sintaxis es mata seguido del nombre de la maquina
if ($#argv != "1") then
echo "Introducir como argumento el nombre de la maquina"
exit
endif
set pid=`rsh $1 ps -feao ruser,pid | grep $user`
foreach pro ($pid)
if ($pro != $user) then
rsh $1 kill -9 $pro
endif
end
El comando switch
La sintaxis del comando es:
switch (string)
case label1:
...
case label2:
.
.
...
breaksw
...
default:
...
breaksw
endsw
Se va comparando si las etiquetas label1, label2 ... coinciden con la cadena string, en cuyo caso se
ejecutan los comandos que van a continuación. en el momento que se encuentre un breaksw continuará con
los comandos que siguen después de endsw. Si no se encuentra ningún breaksw se llega a default: y se
ejecutan los comandos que siguen. Si tampoco hay default: el programa continua su ejecución después
de endsw.
El comando while
La sintaxis es:
while (expr)
...
end
Su funcionamiento es muy simple. Mientras la evaluación de la expresión entre parentesis sea verdadera
(distinto de 0) se ejecutarán los comandos comprendidos entre while y end.
Otros comandos
Existen otros comandos que son muy útiles en la programación en shell, pero que su explicación queda fuera
de los objetivos de este curso. Para los que quieran profundizar en el tema se muestran a continuación los
más importantes con un ejemplo sencillo:
awk (pattern scanning and proccesing language)
Permite buscar patrones de caracteres en ficheros y realizar una serie de acciones cuando encuentra una
coincidencia entre el patrón y una línea. Ejemplos:
awk '$4 ~/agn/ {print $1,$9}' log
Busca el patrón agn en la columna 4 de cualquier línea del fichero log, y para las líneas en que encuentre el
patrón realiza la acción indicada entre {}, que en este caso es mostrar la columna 1 y la 9.
sed
Permite modificar el contenido de un fichero (sustituir palabras, añadir, borrar, etc) según indiquen una serie
de comandos. Un ejemplo sencillo es:
sed -e "s/[Gg]alaxia/NGC4151/g" file
Remplazará en cada línea del fichero file la palabra galaxia o Galaxia por NGC4151.
cut and paste
Cortan y pegan campos seleccionados de cada línea de un ficheros. Ejemplos:
cut -c 1-5 file1
paste l1 l2
El primero extrae por la terminal los cinco primeros caracteres de cada línea del fichero file1. El segundo une
la línea los dos ficheros l1 y l2 mostrandolo por la terminal.

También podría gustarte