Linux Shell
El SHELL es un programa que permite usar comandos que son interpretados o ejecutados para controlar el sistema.
Si bien el shell es un método de interacción del pasado es mas sofisticado para solucionar operaciones que reúnen gran complejidad. Los GUIs en cambio son mas fáciles de usar para tareas relativamente sencillas.
1. Usando el Shell
Cuando se digitan los comandos del shell, se tiene acceso a unmini-editor. Semantiene una lista denominada historical
list. Para reejecutar un comando, presione flecha arriba varias veces hasta localizar el comando y luego presionar Enter
para ejecutar el comando.
Up Retrocede un comando en la history list.
Down Adelanta un comando en la history list.
Left Mueve el Cursor un carácter atrás.
Right Mueve el Cursor un carácter adelante.
Esc f Mueve el Cursor una palabra adelante.
Esc b Mueve el Cursor una palabra atrás.
Ctrl-a Mueve el Cursor el principio de la línea.
Ctrl-e Mueve el Cursor al final de la línea.
Ctrl-d Elimina el Carácter actual.
Backspace Elimina el Carácter anterior.
Esc d Elimina la palabra actual.
Ctrl-u Elimina desde el inicio de línea.
Ctrl k Elimina hasta el fin de línea.
Ctrl-y Deshace la última modificación.
Esc . Inserta la última palabra del comando anterior.
Ctrl-L Limpia el terminal.
Tab Intenta completar la actual palabra, interpretando como fichero, nombre de usuario, nombre de variable o
comando el cual es determinado por el contexto.
Esc ? Lista los posibles compleciones.
Adicionalmente los shell interpretan la siguiente secuencia:
Ctrl-C Envía una señal de interrupción al proceso actual en ejecución, el cual concluye con la finalización de la aplicación.
Ctrl-D Envía una finalización de flujos.
Ctrl-Z Suspende la ejecución del proceso actual.
Otros caracteres especiales:
# Marca el comando como comentario, es ignorado por el shell.
; Separa comandos, permite ingresar comandos en una sola linea.
& Colocado después de una comando, envía el proceso a una ejecución en segundo plano.
2. Comandos y Argumentos
La forma general de un comando de shell tiene la forma:
command options arguments
Donde command determina que operación realizará el shell, las options y arguments añaden preferencias.Muchas veces el
command especifica el nombre de archivo de un programa, el cual debe ser iniciado, comando externo. Los ejecutables se
guardan en las carpetas /bin, /usr/bin o /usr/local/bin. Las aplicaciones de administración de sistema en /sbin o /usr/sbin.
El shell puede interpretar los siguientes meta caracteres para que designan a nombres de archivos y conjunto de ellos.
Carácter Significado
* Empareja una cadena de cero o mas caracteres
? Empareja exactamente un carácter
[ abc ... ] Empareja uno de los caracteres especificados
[ a - z ] Empareja los caracteres en el rango especificado
[ ! abc ... ] Empareja caracteres que no concuerdan con los especificados
[ ! a - z] Empareja caracteres que no concuerdan con el rango especificado
~ El nombre del usuario actual
~userID El nombre del usuario especificado
~+ El directorio de trabajo actual
~- El directorio de trabajo anterior
3. Alias
Facilita el uso de comandos permitiendo nombres abreviados para los comandos y sus argumentos comúnmente usados.
alias name=’commando options arguments’
Donde command especifica el comando para el cual se desea crear un alias. name especifica el alias.
alias dir=’ls -l’
alias fm=’mount -t vfat /dev/fd0 /mnt/floppy’
alias fu=’umount /mnt/floppy’
Su configuración por defecto probablemente define varios alias, para listarlos:
alias
Si inicio sesión como administrador su lista puede ser:
alias cp=’cp -i’
alias dir=’ls -l’
alias cp=’cp -i’
alias ls=’ls --color’
alias mv=’mv -i’
alias rm=’rm -i’
Para remover los alias use el comando unalias.
unalias name
4. Scripts
Un script de shell es simplemente un archivo que contiene comandos, para posteriormente ser ejecutados una y otra
vez.
Por ejemplo considere un archivo denominado deleter, que contiene las siguientes lineas:
echo -n Eliminando archivos temporales ...
rm -fr /tmp/*
echo Done.
Para ejecutar este script:
sh deleter
Si se invoca el comando sh sin argumento que nombre a un script, se lanza una instancia del SHELL para retornar a la
sesión anterior use el comando exit.
Para facilitar la ejecución del script cambie el acceso de ejecución:
chmod ugo+x deleter
./deteler Para ejecutar desde el directorio de trabajo.
PATH/deleter Para ejecutar siguiendo su ruta absoluta o relativa.
deleter Para ejecutar siguiendo la ruta de búsqueda.
Linux incluye varios script estándares que pueden ser ejecutados dependiendo del momento.
/etc/profile Ejecutado cuando el usuario inicia sesión
~/.profile Ejecutado cuando el usuario inicia sesión.
~/.bashrc Ejecutado cuando el BASH es lanzado.
~/.bash_logout Ejecutado cuando el usuario abandona la sesión.
5. Redireccionamiento
El SHELL proporciona tres flujos estándares:
stdin El flujo estándar de entrada
stdout El flujo estándar de salida
stderr El flujo estándar de errores
Por defecto, los programas leen su entrada desde el flujo stdin y escribe su salida al flujo stdout. Porque ambos flujos
son normalmente asociados a las consolas (teclado y pantalla de consola respectivamente). El flujo stderr es asociado
a la pantalla de la consola.
Aunque el SHELL asocia por defecto los tres flujos de entrada/salida con la consola, se pueden especificar redirectores
de entrada/salida que por ejemplo asocie una entrada o una salida con un archivo.
> file Redirecciona el flujo de salida estándar al archivo especificado.
2> file Redirecciona el flujo de error estándar al archivo especificado.
> > file Redirecciona el flujo de salida estándar al archivo especificado, añadiendo salida al archivo si el archivo
existe.
2> > file Redirecciona el flujo de error estándar al archivo especificado, añadiendo salida al archivo si el archivo
existe.
&> file Redirecciona el flujo de salida y error estándar al archivo especificado.
< file Redirecciona el flujo de entrada estándar al archivo especificado.
< < text Lee el flujo de entrada estándar hasta encontrar el patrón text, en cuyo es interpreta como el final del flujo.
cmd1 | cmd2 Se toma la entrada estándar del cmd2 desde la salida estándar de cmd1 (también conocido como canal de
redirección)
Que hacen los comandos:
wc /etc/passwd
wc /etc/passwd > total
cat total
wc
wc < /etc/passwd
Muchos programas son escritos de modo que ignoren la redirección. Por ejemplo el comando passwd. espera leer la
contraseña únicamente desde la consola, no desde un archivo.
Muchos programas Linux leen su entrada desde el flujo stdin y escriben su salida al flujo stdout, estos programas
son denominados filtros. Estros programas pueden ser usados en conjunto para realizar complejas operaciones. La
herramienta para combinar los filtros es el pipe, el cual conecta la salida de un programa a la entrada de otro.
ls -l ~ | wc -l
6. Variables Shell
El SHELL es un lenguaje de programación en sus propios teminos, permitiendo referirse a sus variables conocidas
como variables shell o variables de entorno.
Para asignar un valor a una variable shell use el siguiente esquema.
Variable=valor
Asigna el valor valor al la variable Variable.
Las variables shell son ampliamente usadas dentro de Linux, porque proporciona una via para transferir datos de una
comando a otro. Para listas todas las variables de entorno invoque al comando set. Los valores de esas variables son
establecidas por scripts de inicio.
#!/bin/bash
Nombre=’Linux user..’
echo "Hello:"
echo $Nombre
echo
Algunas variables de entorno:
DISPLAY La vista X a ser usada: por ej. localhost:0
HOME La ruta absoluta del home del usuario.
HOSTNAME El nombre del equipo.
LOGNAME El alias del usuario.
MAIL La ruta absoluta del buzón de correo del usuario.
PATH La ruta de búsqueda.
SHELL La ruta absoluta del actual SHELL.
TERM El nombre del terminal.
USER El nombre del usuario; difiere del login si se ejecuto el comando su.
Se puede usar el valor de la variable shell precediéndola por el signo $.
cd $HOME
cd ${HOME}
Par imprimir el valor de una variable use la variable como argumento del comando echo.
echo $HOSTNAME
Para hacer disponible una variable de shell a otros programas invocados por el shell deben ser exportadas.
export Variable
export VariableX=ValorY
Variable= Para remover el valor asociado con la variable:
unset Variable Para eliminar la varible:
7. La ruta de Búsqueda
La variable de entorno PATH contiene una serie de rutas separadas por “:” conocida como ruta de búsqueda. Cuando
se invoca a un comando externo el SHELL usa la ruta de búsqueda para hallar el nombre de archivo que corresponde al
comando. Los scripts de inicio establecen los valores iniciales para PATH, para modificar su valor redefina la añadiendo
al valor anterior las nuevas rutas:
PATH=${PATH}:/home/user
El comando which verifica la ruta de búsqueda para el argumento indicado e imprime la ruta del nombre encontrado si
existe.
which wc
8. Entrecomillado
Permiten la correcta interpretación para el SHELL.
’ Caracteres incluidos dentro de un par de simple comillas son interpretados literalmente.
“” Caracteres incluidos dentro de un par de doble comillas son interpretados literalmente. Además se reemplazan
las variables de entorno con el valor referenciado.
“ Caracteres incluidos dentro de un par de comillas invertidas son interpretados como un comando el cual
es ejecutado antes de ejecutar el resto de comandos de la linea. La salida del comando remplaza la cadena
original.
\ El siguiente carácter es interpretado literalmente. Se ignora los metacaracteres.
Interprete cada linea:
echo $PATH
echo ’$PATH’
echo “$PATH”
echo Mi directorio personal contiene ‘ls ~ | wc -l‘ Archivos.
Ejecute el siguiente programa
#!/bin/bash
DIR=/tmp
Cadena1="ls -l $DIR"
Cadena2=’ls -l $DIR’
Cadena3=\$DIR
Cadena4=‘ls -l $DIR‘
echo
echo "Cadena1: "$Cadena1
echo "Cadena2: "$Cadena2
echo "Cadena3: "$Cadena3
echo "Cadena4: "$Cadena4
Ahora puede apreciar el poder del SHELL de Linux: Incluyendo sus alias en el script de inicio .bashrc, usando el auto
completado de comandos, usando la lista histórica. Pero el SHELL tiene características que extienden sus capacidades
como la de incluir un lenguaje de programación que proporciona el procesamiento de argumentos, condiciones, lógicas,
bucles, subprogramas y recursividad.
9. Procesando Argumentos
Cuando se llama a un programa (comando) se añade información adicional por ejemplo:
ls -l /tmp
este comando tiene dos parámetros:
1) -l
2) /tmp
Los parámetros dentro de un script se recuperar con las variables especiales: $1, $2, ..., $9.
Además:
$# Indica el numero de parámetros pasados al script.
$0 El nombre del script.
$1,$2,...,$9 Cada uno de los argumentos.
$* Cadena con todos los parámetros, tratado como una palabra simple.
$@ Cadena con todos los parámetros, tratado como una serie de palabras.
$? Código de salida del comando previo. Un valor 0 señala que termino sin errores.
$$ El identificador de proceso.
Advierta que el shell le proporciona variables para acceder solo a nueve argumentos. Para acceder al resto de parámetros
use el comando shift que descarta el primer parámetro y desplaza la lista hacia la izquierda.
La variable $? contiene un código de salida numérico del anterior comando. Por convención un código de 0 denota un
termino sin errores; en cambio otros valores indican condiciones de error. Un script puede terminar indicando un código
de finalización con el comando:
exit status
donde status es un entero no negativo que indica el código de salida.
Invoque el siguiente script con dos parámetros
#!/bin/bash
echo
echo "El primer parametro: "$1
echo "El segundo parametro: "$2
echo "Numero de parametros es: "$#
echo "El nombre del script es: "$0
echo "Los parametros son: "$*
echo "Los parametros son: "$@
echo
10. Comparación de Expresiones
La comparación lógica de dos operadores (numéricos o cadenas) tiene la sintaxis:
test expresion
[ expresion ]
Comparación de cadenas:
s1 = s2 Para comparar si dos cadenas son iguales.
s1 != s2 Para comparar si dos cadenas no son iguales.
-n s1 Para evaluar si la longitud de la cadena es mayor que cero.
-z s1 Para evaluar si la longitud de la cadena es cero.
Comparación numérica:
n1 -eq n2 igual que
n1 -ge n2 mayor o igual que
n1 -le n2 menor o igual que
n1 -ne n2 no es igual que
n1 -gt n2 mayor que
n1 -lt n2 menor que
Operadores de archivos:
-e file existe
-d file existe y es directorio
-f file existe y es archivo
-c file existe y es un archivo de dispositivo de caracteres
-b file existe y es un archivo de dispositivo de bloques
-r file existe y tiene permiso de lectura
-s file existe y tiene longitud mayor a cero
-w file existe y tiene permiso de escritura
-x file existe y tiene permiso de ejecución
-h file existe y es un enlace
f1 -nt f2 el archivo f1 es mas reciente que f2
f1 -ot f2 el archivo f1 es mas antiguo que f2
Operadores lógicos:
! el operador NOT, invierte el valor de la siguiente condición .
-a el operador lógico AND
-o el operador lógico OR
11. Evaluación Aritmética
Las variables SHELL pueden contener números, pero en general todos son tratados como cadenas de caracteres. La
aritmética entera se puede manejar con el comando interno let o con el comando externo expr.
#!/bin/bash
NUM=1024
let X=$NUM/16
Y=‘expr $NUM / 256‘
echo “Calculo con let: ”$X
echo “Calculo con expr: ”$Y
El comando interno let exige que no se incluyan espacios entre los operandos y operadores; en cambio el comando externo
expr exige espacios.
Operadores matemáticos let
+ - incremento y decremento
+ - * /% suma, resta, multiplicación división y resto
< <= > >= == != comparaciones: menor que, menor o igual que, mayor que, mayor o igual
que, igual, diferente
& ^ | ~ AND, XOR, OR y NOT a nivel de bits
< < > desplazamiento a la izquierda y desplazamiento a la derecha a nivel de bits
&& || ! operadores lógicos AND, OR y NOT
= *= /=%= += -= < <= >= &= ^= |= asignaciones
Operadores matemáticos expr
+ - * /% suma, resta, multiplicación división y resto
< <= > >= = != comparaciones: menor que, menor o igual que, mayor que, mayor o igual
que, igual, diferente
& | operadores lógicos AND y OR
12. Sentencia if:
if [ expresion ]
then
fi
if [ expresion ]
then
else
fi
if [ expresion ]
then
elif [ expresion ]
else
fi
Codifique e invoque con los parámetros apropiados los siguientes scripts:
#!/bin/bash
if [ $1 -ge 0 ] ; then
echo "El numero es positivo o nulo"
fi
#!/bin/bash
if [ $1 -ge 0 ] ; then
echo "El numero es positivo o nulo"
else
echo "El numero es negativo"
fi
#!/bin/bash
if [ $1 -gt 0 ] ; then
echo "El numero es positivo"
elif [ $1 -eq 0 ] ; then
echo "El numero es nulo"
else
echo "El numero es negativo"
fi
13. Sentencia case
Es una sentencia de selección múltiple
case str in
str1) sentencias;;
str2) sentencias;;
*) sentencias;;
esac
Codifique e invoque con un parámetro numérico:
#!/bin/bash
case $1 in
1 | 01) echo "Mes de Enero";;
2 | 02) echo "Mes de Febrero";;
3 | 03) echo "Mes de Marzo";;
4 | 04) echo "Mes de Abril";;
5 | 05) echo "Mes de Mayo";;
6 | 06) echo "Mes de Junio";;
7 | 07) echo "Mes de Julio";;
8 | 08) echo "Mes de Agosto";;
9 | 09) echo "Mes de Septiembre";;
10) echo "Mes de Octubre";;
11) echo "Mes de Noviembre";;
12) echo "Mes de Diciembre";;
*) echo "Parametro invalido";;
esac
14. Sentencia for
La sentencia for itera sobre los elementos de una lista:
for var in lista
do
sentencias
done
#!/bin/bash
for Mes in 1 2 3 4 5 6 7 8 9 10 11 12
do
cal $Mes 2004
done
Ejecute este script añadiendo una lista de parámetros
#!/bin/bash
for Mes in "$@"
do
cal $Mes 2004
done
15. Sentencia while
Se ejecuta las sentencias mientras la expresión resulte verdadera
while expresion
do
sentencias
done
#!/bin/bash
num=1 sum=0
while [ $num -le 5 ]
do
sum=‘expr $sum + $num‘
num=‘expr $num + 1‘
done
echo "La suma es: $sum"
16. La sentencia until
Se ejecuta las sentencias hasta que se cumpla la condición
until expresion
do
sentencias
done
#!/bin/bash
num=1 sum=0
until [ $num -gt 5 ]
do
sum=‘expr $sum + $num‘
num=‘expr $num + 1‘
done
echo "La suma es: $sum"
17. Otras sentencias
Sentencia break Se usa para salir de un bucle: for until o while
Sentencia continue Se usa para iniciar el siguiente ciclo de un bucle: for until o while
Sentencia exit Se utiliza para salir de un script, puede tener ser acompañado de un parámetro de salida.
18. Funciones
Cuando se invoca a un subprograma: func param1 param2 param 3 un subprograma puede analizar los parámetros
pasados de forma idéntica a alas de un guión.
func () {
#sentencias
}
Ejemplo de subprograma:
#!/bin/bash
MuestraMes() {
case $1 in
1 | 01) echo "Mes de Enero";;
2 | 02) echo "Mes de Febrero";;
3 | 03) echo "Mes de Marzo";;
4 | 04) echo "Mes de Abril";;
5 | 05) echo "Mes de Febrero";;
6 | 06) echo "Mes de Mayo";;
7 | 07) echo "Mes de Junio";;
8 | 08) echo "Mes de Agosto";;
9 | 09) echo "Mes de Septiembre";;
10) echo "Mes de Octubre";;
11) echo "Mes de Noviembre";;
12) echo "Mes de Diciembre";;
*) echo "Parametro invalido";;
esac
}
MuestraMes 8
Imprime una pagina que indiza las paginas html de cada subdirectorio.
#!/bin/bash
echo ’<html>’
echo ’<head>’
echo ’<title> My Index </title>’
echo ’</head>’
echo ’<body>’
echo ’<h1>Index of HTML files </h1>’
for i in *
do
if [ -d $i ] ; then
echo "<h2>$i</h2>"
echo ’<ul>’
for j in $i/*.htm*
do
if [ -f $j ] ; then
tline=‘grep ’<TITLE>’ $j‘
if [ $? -eq 1 ]
then
ntitle=‘basename $j | cut -f1 -d"."‘
else
ntitle=‘echo $tline | sed ’s/^.*<title>//’ | sed ’s/<\/title>.*$//’‘
fi
echo "<li><a href=$j>$ntitle</a>"
fi
done
echo ’</ul>’
fi
done
echo ’</body>’
echo ’</html>’
Programa que muenta un cdrom:
#!/bin/ash
PM=’/dev/hda’
PS=’/dev/hdb’
SM=’/dev/hdc’
SS=’/dev/hdd’
DEVICES="$PM $PS $SM $SS /dev/sr0"
DEVCD=
#Montar el CDROM
if [ ! -d /cdrom ] ; then
mkdir /cdrom
fi
for DEV in $DEVICES
do
echo $DEV
mount -t iso9660 $DEV /cdrom 2> /dev/null
if [ $? -eq 0 ] ; then
DEVCD=$DEV
ln -s $DEV /dev/cdrom 2>/dev/null
break
fi
done
if [ -z $DEVCD ] ; then
echo "CDrom no Encontrado ..."
exit 1
fi
Programa que carga al PostgreSQL
#! /bin/sh
PG_SYSCONFIG=/etc/sysconfig/postgresql
if [ -f $PG_SYSCONFIG ]; then # SuSE Linux 8.0 and above
. $PG_SYSCONFIG
else # SuSE Linux up to 7.3
. /etc/rc.config
base=${0##*/}
link=${base#*[SK][0-9][0-9]}
test $link = $base && START_POSTGRES=yes
test "$START_POSTGRES" = yes || exit 0
fi
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v ditto but be verbose in local rc status
# rc_status -v -r ditto and clear the local rc status
# rc_failed set local and overall rc status to failed
# rc_reset clear local rc status (overall remains)
# rc_exit exit appropriate to overall rc status
. /etc/rc.status
H=/usr/bin/postmaster
test -x $H || exit 5
LOGFILE=/var/log/postgresql
eval DATADIR=${POSTGRES_DATADIR:-~postgres/data}
OPTIONS=${POSTGRES_OPTIONS}
# The echo return value for success (defined in /etc/rc.config).
rc_reset
# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
#
# Note that starting an already running service, stopping or restarting a not-running
# service as well as the restart with force-reload (in case signalling is not supported)
# are considered a success.
case "$1" in
start)
if [ ! -f $DATADIR/PG_VERSION ]; then
echo -n "Initializing the PostgreSQL database at location ${DATADIR}"
install -d -o postgres -g daemon -m 700 ${DATADIR} &&
su - postgres -c "env -i initdb $DATADIR &> initlog" || rc_failed
rc_status -v
rc_status || {
echo "You can find a log of the initialisation in ~postgres/initlog."
rc_exit
}
fi
echo -n "Starting PostgreSQL"
BIN_VERSION=$(/usr/bin/postgres --version|sed ’s/.* \([0-9]\+\.[0-9]\+\).*/\1/’)
DATA_VERSION=$(cat $DATADIR/PG_VERSION)
if [ "$BIN_VERSION" != "$DATA_VERSION" ]; then
echo ""
echo " Installed binaries and database files don’t match."
echo " Manual work is needed to upgrade your database."
echo " See /usr/share/doc/packages/postgresql/README.SuSE for details."
echo -n "Starting PostgreSQL "
rc_failed
rc_status -v
rc_exit
else
## remove old socket, if it exists and no daemon is running.
checkproc $H || rm -f /tmp/.s.PGSQL.5432
## Start daemon with startproc(8). If this fails
## the echo return value is set appropriate.
/sbin/startproc -e -t 1 -u postgres -l $LOGFILE $H $OPTIONS -D$DATADIR
rc_status -v
fi
;;
stop)
echo -n "Shutting down PostgreSQL"
## Stop daemon with killproc(8) and if this fails
## set the echo return value.
killproc -INT $H
rc_status -v
;;
try-restart)
## Stop the service and if this succeeds (i.e. the
## service was running before), start it again.
## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
$0 status && $0 restart
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
rc_status
;;
force-reload | reload)
echo -n "Reloading configuration for PostgreSQL"
killproc -HUP $H
rc_status -v
;;
status)
echo -n "Checking for PostgreSQL: "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
# Status has a slightly different for the status command:
# 0 - service running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running
# NOTE: checkproc returns LSB compliant status values.
checkproc $H
rc_status -v
;;
probe)
rc_failed 3
rc_status -v
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
exit 1
;;
esac
# Inform the caller not only verbosely and set an exit status.
rc_exit