Modulo 5 - Shells de Linux
Modulo 5 - Shells de Linux
Módulo 5
SHELLS DE LINUX
Objetivos
Los participantes al finalizar la Unidad:
Temario
5.1 Comprensión de los shells
5.2 Metacaracteres
5.3 Entrada y salida de Comandos (redirecciones)
5.4 Alias de comandos de shell
5.5 Comprensión de los shell scripts
Examen
Los participantes deberán rendir el examen online o presentar el material solicitado según
corresponda.
El shell no es parte del kernel del sistema pero utiliza al mismo para
ejecutar programas, crear archivos, etc. Es un intérprete que ejecuta los
comandos leídos del dispositivo de entrada estándar (teclado por ejemplo)
o bien un archivo.
Nombre
Desarrollado por: Detalles
del Shell:
BASH Free Software Es el shell mas comun en
(Bourne Foundation Linux
Again Shell)
CSH (C University of La sintaxis de este shell es
Shell) California muy similar a la del
lenguaje de programación
C
KSH (Korn AT&T BELL Labs --
Shell
TCSH -- TCSH es una versión
mejorada y totalmente
compatible del UNIX C
Shell (CSH)
Cualquiera de los anteriores shells leen los comandos del usuario, a través del teclado o
mouse, y le dicen al sistema operativo lo que el usuario desea hacer. Si los comandos
se están ingresando mediante el teclado se dice que se ingresan mediante línea de comandos.
Sh y bash Shell
Debido al éxito he historia del Bourne Shell utilizado en Unix, utilizado para escribir infinidad
de scripts, es que se han incluido – algunos de ellos – en Linux.
En Linux sh es un link hacia bash. Al ser llamado mediante sh Linux intentara emular lo mejor
posible al Bourne Shell original.
Startup Files
Al arrancar un shell se ejecutan los archivos de inicialización. El shell ejecuta primero los
comandos en /etc/profile
Caracteres especiales
Carácter Descripción
NEWLINE Initiates execution of a command
; ;
() Groups commands for execution by a subshell or identifies a
function
& Executes a command in the background
| Sends standard output of preceding command to standard
input of following command (pipe)
> Redirects standard output
>> Appends standard output
< Redirects standard input
<< Here document
* Any string of zero or more characters in an ambiguous file
reference
? Any single character in an ambiguous file reference
\ Quotes the following character
´ Quotes a string, preventing all substitution
´´ Quotes a string, allowing only variable and command
substitution
´…´ Performs command substitution
[] Character class in an ambiguous file reference
Sintaxis Descripción
cmd & Execute cmd in background
cmd1 ;cmd2 Command sequence
(cmd1 ; cmd2) Execute commands in a subshell
cmd1 | cmd2 Use output from cmd1 as input to cmd2
cmd1 ´cmd2´ Use otput from cmd2 as arguments to cmd1
cmd1 && cmd2 Execute cmd2 only if cmd1 succeeds (AND)
cmd1 || cmd2 Execute cmd2 only if cmd1 fails (OR)
5.2 Metacaracteres
Cuando se trabaja en la línea de comando es muy necesario contar con una
herramienta que nos permita integrar varios nombres de archivos, con el uso de uno o más
caracteres especiales
Esta técnica es muy común en todos, o la mayoría de los shell existentes, pero a pesar de que
en Linux los caracteres que se utilizan son muy parecidos a los utilizados en otros sistemas
operativos, no siempre tienen el mismo significado y/o resultado. En algunos casos el mal uso
de estos metacaracteres puede traernos consecuencias no deseadas
# ls *
a.g.e.n.d.a agenda agenda.
# ls .*
.agenda
.:
a.g.e.n.d.a agenda agenda.
#
Como se puede observar, al ejecutar «ls *» solamente se pudo ver tres archivos: a.g.e.n.d.a,
agenda y agenda.; al ejecutar «ls .* », se visualizó, primero, el archivo «.agenda», luego el
contenido del directorio «.» y por último el contenido del directorio «..».
Como se habrá notado no es necesario utilizar «*.*» para reemplazar todos los archivos
de un directorio. Es necesario destacar que en Linux no existe el concepto de extensión de
archivo como en DOS o Windows. En Linux, como en todos los Unix, un archivo puede
contener varios puntos, al igual que otros carácteres especiales como la coma «,», los dos
puntos «:», etc.
Por lo tanto, si ejecutamos «ls *.*» solamente se verán los archivos que contienen un punto
(después del primer carácter al menos) dentro de su nombre
# ls ?gen*
agen Agenda Lgenda
# ls .?gen*
.agenda
En este ejemplo notamos que el signo de pregunta «?» reemplazo la letra «A», la «a» y la «L»,
pero no el «.». Para poder visualizar el archivo «.agenda» hubo que poner el punto «.»
expresamente
Se entiende por entrada estándar a lo que puede recibir un proceso como ingreso de
información durante su ejecución y salida, todo lo que el proceso devuelve al usuario.
Por ejemplo, la salida estándar del comando «ls» sería el listado de archivos y
directorios que aparece en pantalla. En el caso de la entrada estándar de un comando lo
podríamos ejemplificar con el comando «cat», utilizando como entrada el archivo a imprimir.
En el caso de la salida de error, serían todos los errores que devuelve un comando. Es posible
en Linux, atrapar esta salida y manipularla en forma diferente.
El símbolo mayor se puede utilizar para enviar la salida (estándar o de error) de un proceso a
un archivo o dispositivo. Esto se utiliza para poder monitorear con más detenimiento la salida
de un proceso o utilizar la misma para, luego de algún tipo de edición o manipulación del
archivo creado, utilizarlo como entrada de algún otro proceso, o como simple reporte.
Por la salida de error de un proceso se envían todos los mensajes que produce un comando
cuando éste encuentra un problema.
Para atrapar la salida de error se utiliza el identificador «2». A continuación se pueden observar
algunos ejemplos:
# ls /undirectorioinexistente
ls: cannot access /undirectorioinexistente: No such file or directory
#
Si quisiéramos atrapar el mensaje de error del comando anterior debería hacer lo siguiente:
# ls /undirectorioinexistente 2>/tmp/err.log
# cat /tmp/err.log
ls: cannot access /undirectorioinexistente: No such file or directory
#
El mensaje de error ahora, quedo en el archivo al cual fue redireccionado (en este caso
"/tmp/err.log").
Por la salida estándar de un proceso se envían todos los mensajes que no son considerados
errores. Por ejemplo, la salida del comando ls - el listado de archivos y directorios - es la salida
estándar.
Para atrapar la salida de estándar se utiliza el identificador «1» o ningún identificador, ya que
es el default. A continuación se citan algunos ejemplos:
# ls -FaC /
./ .gnome/ boot/ home/ mnt/ root/ usr/
../ .gnome_private/ dev/ lib/ opt@ sbin/ var/
Como se puede observar, la salida del primer comando fue íntegramente atrapada al
redireccionarla hacia el archivo /tmp/stdout.txt.
# ls -l / > /tmp/salida.txt
# cat /tmp/salida.txt
drwxr-xr-x 2 root root 2048 Nov 4 01:06 bin
drwxr-xr-x 2 root root 1024 Oct 26 10:35 boot
drwxr-xr-x 5 root root 34816 Nov 6 15:58 dev
drwxr-xr-x 30 root root 3072 Nov 6 15:53 etc
drwxr-xr-x 2 root root 12288 Oct 25 19:18 lost+found
drwxr-xr-x 6 root root 1024 Oct 26 14:51 mnt
En el primer comando se redirecciona al archivo /tmp/salida.txt la salida del comando «ls -l /»,
luego, se agrega la salida del comando «ls -FaC /usr/» a este mismo archivo. De esta forma se
obtuvo la salida de dos comandos en un mismo archivo, ya que no se sobrescribió.
En algunos casos es necesario unificar la salida de error y la salida estándar para tener todo
en un mismo archivo. Existen muchas maneras para realizar esto, en este manual sólo se
describe una, ya que es la más tradicional y utilizada.
Para unificar las salidas de un comando, no solo utilizaremos el símbolo &, sino que también
se utilizaran los números 1 y 2 para identificar la salida estándar y de error, respectivamente.
Como se puede observar el directorio /VariableS no existe; no es el caso del directorio /var.
# cat /tmp/Salida-y-Error.txt
ls: /VariableS: No such file or directory
./ cache/ db/ lib/ lock/ nis/ run/ tmp/
../ catman/ gdm/ local/ log/ preserve/ spool/ yp/
Es importante tener en cuenta el orden que se utilizan en las unificaciones, el 2>&1 va al final
En la sección anterior se vio como hacer para enviar las salidas a un archivo, existe también la
manera de utilizar la salida de un proceso como entrada de otro proceso. Para realizar esto
utilizaremos pipes (cañerías en inglés) y se simbolizan con este carácter: «|»
# ls -l
total 65
drwxr-xr-x 2 root root 2048 Nov 4 01:06 bin
drwxr-xr-x 2 root root 1024 Oct 26 10:35 boot
drwxr-xr-x 5 root root 34816 Nov 6 15:58 dev
drwxr-xr-x 30 root root 3072 Nov 6 15:53 etc
drwxr-xr-x 6 root root 1024 Oct 26 13:52 home
drwxr-xr-x 4 root root 3072 Oct 25 19:26 lib
drwxr-xr-x 2 root root 1228 Oct 25 19:18 lost+found
drwxr-xr-x 6 root root 1024 Oct 26 14:51 mnt
# ls -l | grep home
drwxr-xr-x 6 root root 1024 Oct 26 13:52 home
drwxr-xr-x 8 root root 1024 Oct 28 21:30 vhome
#
Esta herramienta es muy poderosa y se puede utilizar en forma encadenada, teniendo varios
procesos unidos por pipe.
Bifurcaciones (TEE)
Cuando la cadena de pipes es muy larga y necesitamos ver la salida de un comando que está
en el medio de esa cadena, se puede utilizar la bifurcación de pipes, esta técnica nos permite
guardar en un archivo todo los caracteres que están pasando en ese lugar del pipe, y también
enviarlo como salida del proceso (o entrada del proceso siguiente). De esta forma obtendrá en
un archivo la información requerida y no romperá la cadena de pipes.
# cat /tmp/bif.txt
total 65
drwxr-xr-x 2 root root 2048 Nov 4 01:06 bin
drwxr-xr-x 2 root root 1024 Oct 26 10:35 boot
drwxr-xr-x 5 root root 34816 Nov 6 15:58 dev
drwxr-xr-x 30 root root 3072 Nov 6 15:53 etc
drwxr-xr-x 6 root root 1024 Oct 26 13:52 home
drwxr-xr-x 4 root root 3072 Oct 25 19:26 lib
drwxr-xr-x 2 root root 12288 Oct 25 19:18 lost+found
drwxr-xr-x 6 root root 1024 Oct 26 14:51 mnt
lrwxrwxrwx 1 root root 10 Oct 26 16:35 opt -> /usr/local
dr-xr-xr-x 74 root root 0 Nov 4 19:44 proc
drwxr-x--- 13 root root 1024 Nov 6 16:17 root
drwxr-xr-x 3 root root 2048 Nov 4 01:06 sbin
drwxrwxrwt 15 root root 1024 Nov 6 17:21 tmp
drwxr-xr-x 20 root root 1024 Nov 4 01:04 usr
drwxr-xr-x 16 root root 1024 Oct 25 19:28 var
drwxr-xr-x 8 root root 1024 Oct 28 21:30 vhome
De esta forma, la cadena de pipes sigue respondiendo como antes, pero se obtuvo un archivo
con lo que estaba transitando por la cadena.
Esto es muy útil cuando tenemos problemas dentro de una cadena larga y necesitamos
ver el contenido de un paso, sin romper la cadena de pipes
Alias es un comando que posibilita el reemplazo de una palabra por otra serie de palabras. Se
utiliza para abreviar un comando o bien para agregar argumentos a un comando muy utilizado.
Los alias se creen en el momento mediante la sentencia <alias> y el par nombre argumento
# ls
agen a.g.e.n.d.a Agenda archivo error.log Lgenda
#
# alias ls='ls -la'
#
# ls
total 16
drwxr-xr-x 9 root root 1024 2008-11-02 08:07 .
drwxr-xr-x 22 root root 1024 2008-10-25 21:06 ..
-rw-r--r-- 1 root root 0 2008-11-01 13:19 agen
-rw-r--r-- 1 root root 0 2008-11-01 13:20 .agenda
-rw-r--r-- 1 root root 0 2008-11-01 13:19 a.g.e.n.d.a
-rw-r--r-- 1 root root 0 2008-11-01 13:18 Agenda
drwx------ 2 root root 1024 2008-10-25 18:53 .aptitude
-rw-r--r-- 1 root user 0 2008-10-30 00:44 archivo
-rw------- 1 root root 2756 2008-11-02 08:06 .bash_history
-rw-r--r-- 1 root root 429 2008-11-02 07:48 .bashrc
Para ver los alias definidos en sistema utilizamos el mismo comando pero sin
parámetros
# alias
alias l=´ls -CF´
alias la=´ls -A´
alias ll='ls -l'
alias ls='ls --color=auto'
# ll
total 52068
-rw-r--r-- 1 user user 1734 2008-10-26 01:08 61B8DB62.gpg
drwxr-xr-x 3 user user 4096 2008-11-02 07:51 Desktop
-rw-r--r-- 1 user user 53236677 2008-05-16 02:28 VMwareTools.tar.gz
drwxr-xr-x 7 root root 4096 2008-05-16 02:28 vmware-tools-distrib
#
En caso de ya existir un alias de un comando es posible imponerse a el por medio del uso de
comillas.
# unalias ls
#
# ls
agen a.g.e.n.d.a Agenda archivo error.log Lgenda
Es una serie de comandos escritos en texto plano en un archivo. Este archivo se pasa a un
intérprete de comandos que realizara las acciones programadas en el script.
# vi prueba.sh
#!/bin/sh
#
# Mi primer script
#
clear
echo "Knowledge is
Power"
:wq
# chmod +x prueba.sh
Ejecutar el script
$ bash prueba.sh
$ sh prueba.sh
$ ./prueba.sh
Para que el sistema llame al intérprete correcto nuestro script debe indicar al
comienzo cual es el intérprete que utilizamos
#!/bin/bash
#!/bin/sh
Comentarios
#!/bin/bash
# Este es un script de ejemplo para el curso Operador Linux
Variables
VAR1=”contenido”
Y para ver el contenido de la variable la debemos llamar mediante el símbolo $. Por ejemplo
para imprimir en pantalla el contenido de la variable VAL1 haremos lo siguiente
echo $VAR1
Hay ciertas variables que pertenecen al sistema operativo y podrán ser utilizadas por nuestro
script, podemos citar las siguientes
Estado de salida
Al finalizar la ejecución de un comando o script Linux devuelve dos tipos de valores utilizados
para saber si la ejecución finalizo correctamente o no.
#!/bin/bash
# Este es un script de ejemplo para el curso Operador Linux
clear
#./prueba.sh 5 3
Primer parámetro: 5
Segundo parámetro: 3
Cantidad de parámetros: 2
Parámetros concatenados: 5 3
Suma de los parámetros:
8
0 esta es la salida de error
#./prueba.sh 5 texto
Primer parámetro: 5
Segundo parámetro: texto
Cantidad de parámetros: 2
Parámetros concatenados: 5 texto
Suma de los parámetros:
expr: non-numeric argument
3 esta es la salida de error
La sentencia read
Se utiliza para ingresar datos por medio del teclado y cargarlos en variables. Esta sentencia
detiene el script hasta que se introduzcan datos por línea de comandos.
#!/bin/bash
# Este es un script de ejemplo para el curso Operador Linux
clear
echo “Ingrese su nombre”
read nombre
echo “Bienvenido al sistema $nombre, espero que disfrute su estadía!”
Comparaciones
#!/bin/bash
# Este es un script de ejemplo para el curso Especialista Linux
clear
echo “Ingrese su nombre”
read nombre
if [ -z $nombre ] ;then
echo “No ha ingresado si nombre”
else
echo “ Bienvenido al sistema $nombre, espero que disfrute su estadía!”
Operadores Lógicos
#!/bin/bash
# Este es un script de ejemplo para el curso Especialista Linux
clear
echo “Ingrese un numero”
read numero
if test $numero -gt 0
then
echo "$numero es un numero positivo"
fi
La sentencia if
#!/bin/sh
# Este es un script de ejemplo para el curso Especialista Linux
#
if cat $1
then
echo -e "\n\nArchivo $1, archivo encontrado y mostrado en pantalla"
fi
#!/bin/sh
# Este es un script de ejemplo para el curso Especialista Linux
if [ $# -eq 0 ]
then
echo "$0 : Debe introducir un numero entero como argumento"
exit 1
fi
if test $1 -gt 0
then
echo "$1 es positivo"
else
echo "$1 es negativo"
fi
Esta sentencia crea una variable que servirá para contabilizar las iteraciones. El proceso
continuara hasta que se terminen las iteraciones.
#!/bin/sh
#
if [ $# -eq 0 ]
then
echo "Error - debe ingresar un argumento en la línea de comando"
echo "Sintaxis: $0 numero"
echo "Utilizado para imprimir la tabla de multiplicar del numero dado"
exit 1
fi
n=$1
for i in 1 2 3 4 5 6 7 8 9 10
do
echo "$n * $i = `expr $i \* $n`"
done
Sentencia while
#!/bin/sh
#
if [ $# -eq 0 ]
then
echo "Error - debe ingresar un argumento en la línea de comando"
echo "Sintaxis: $0 numero"
echo "Utilizado para imprimir la tabla de multiplicar del numero dado"
exit 1
fi
n=$1
i=1
while [ $i -le 10 ]
do
echo "$n * $i = `expr $i \* $n`"
i=`expr $i + 1`
done
#!/bin/sh
#
if [ -z $1 ]
then
renta="*** Vehiculo desconocido ***"
elif [ -n $1 ]
then
renta=$1
fi
case $renta in
"auto") echo "El alquiler de $renta es de \$20 por km";;
"camioneta") echo " El alquiler de $renta es de \$50 por km ";;
"jeep") echo " El alquiler de $renta es de \$5 por km ";;
"bici") echo " El alquiler de $renta es de \$2 por km ";;
*) echo "Lo sentimos, no podemos alquiarle un $renta";;
Esac
#!/bin/bash
# Este es un script de ejemplo para el curso Operador Linux
clear
echo “Ingrese su nombre”
read nombre
if [ -z $nombre ] ;then
echo “No ha ingresado si nombre”
else
echo “ Bienvenido al sistema $nombre, espero que disfrute su estadía!”