martes, 3 de octubre de 2017

Introducción

Introducción
¿Por qué usar la línea de comandos?
¿De qué trata este libro?
¿Quién debería leer este libro?
¿Qué hay en este libro?
¿Cómo leer este libro?
¿Por qué no lo llamo “GNU/Linux”?
Agradecimientos
¡Necesito tu ayuda!
¿Qué hay nuevo en The Second Internet Edition?
Para saber más
Colofón

Parte 1 – Conociendo el Shell

1- ¿Qué es el Shell?
Emuladores de Terminal
Tus primeras pulsaciones en el teclado
Historial de Comandos
Movimiento del Cursor
Unas palabras sobre el Ratón y el Foco
Prueba algunos comandos sencillos
Finalizando una sesión de terminal
La consola tras el telón
Resumiendo
Para saber más
2 - Navegación
Entendiendo el árbol del sistema de archivos
El directorio de trabajo actual
Listando los contenidos de un directorio
Cambiando el directorio de trabajo actual
Rutas Absolutas
Rutas Relativas
Algunos atajos útiles
Aspectos importantes sobre nombres de archivo
Resumiendo
3- Explorando el sistema
Más diversión con ls
Opciones y argumentos
Un vistazo más profundo al formato largo
Averiguando el tipo de archivo con file
Viendo el contenido de un archivo con less
¿Qué es “texto”?
Menos es Más (Less is More)
Una visita guiada
Enlaces Simbólicos
Enlaces duros
Resumiendo
Para saber más
4 - Manipulando archivos y directorios
Comodines
Rangos de caracteres
Los comodines también funcionan en la GUI
mkdir – Crear directorios
cp – Copiar archivos y directorios
Opciones útiles y ejemplos
mv – Mover y renombrar archivos
Opciones útiles y ejemplos
rm – Eliminar archivos y directorios
Opciones útiles y ejemplos
¡Ten cuidado con rm!
ln – Crear Enlaces
Enlaces duros
Enlaces simbólicos
Construyamos un terreno de juego
Creando directorios
Copiando archivos
Moviendo y renombrando archivos
Creando enlaces duros
Creando enlaces simbólicos
Eliminando archivos y directorios
Creando enlaces simbólicos con la GUI
Resumiendo
Para saber más
5 - Trabajando con comandos
¿Qué son exactamente los comandos?
Identificando comandos
type – Muestra de qué tipo es un comando
which – Muestra la localización de un ejecutable
Obteniendo la documentación de un comando
help – Ofrece ayuda sobre los shell builtins
--help – Muestra información de uso
man – Muestra el manual de un programa
apropos – Muestra comandos apropiados
whatis – Muestra una descripción muy breve de un comando
La man page más brutal de todas
info – Muestra un archivo de información de un programa
README y otros archivos con documentación de programas
Creando tus propios comandos con alias
Resumiendo
Para saber más
6- Redirección
Entrada, salida y error estándar
Redirigiendo la salida estándar
Redirigiendo el error estándar
Redirigiendo la salida estándar y el error estándar a un archivo
Eliminando salidas innecesarias
/dev/null en la cultura Unix
Redireccionando la entrada estándar
cat – Concatenando archivos
Pipelines (Tuberías)
La diferencia entre > y |
Filtros
uniq – Muestra u omite líneas repetidas
wc – Muestra el número de líneas, palabras y bytes
grep – Imprime líneas que coinciden con un patrón
head / tail – Muestra la primera/última parte de los archivos
Tee – Lee de stdin y lo pasa a stdout y a archivos
Resumiendo
Linux tiene que ver con la imaginación
7 - Viendo el mundo como lo ve el shell
Expansión
Expansión de nombres de archivo
Expansión de nombres de archivos ocultos
Expansión de la tilde de la ñ
Expansión aritmética
Expansión con llaves
Expansión con parámetros
Sustitución de comandos
Entrecomillado
Comillas dobles
Comillas simples
Caracteres de escape
Secuencias de escape con la barra invertida
Resumiendo
Para saber más
8 - Trucos avanzados del teclado
Edición de la línea de comandos
Movimiento del cursor
Modificando el texto
Cortar y pegar (Killing and Yanking) texto
La Meta tecla
Completado
Completado programable
Usando el historial
Buscando en el Historial
Expansión del historial
script
Resumiendo
Para saber más
9 - Permisos
Propietarios, miembros del grupo, y todos los demás
Leer, escribir y ejecutar
chmod – Cambiando el "modo" (los permisos) de un archivo
¿Qué diablos es octal?
Configurando los permisos de un archivo con la GUI
umask – Establecer los permisos por defecto
Algunos permisos especiales
Cambiar identidades
su – Ejecutar un Shell con Ids sustitutos de usuarios y grupos
sudo – Ejecutar un comando como otro usuario
Ubuntu y sudo
chown – Cambia el propietario y el grupo de un archivo
chgrp – Cambiando el grupo propietario
Ejercitando nuestros privilegios
Cambiando tu contraseña
Resumiendo
Para saber más
10 - Procesos
Cómo funciona un proceso
Viendo los procesos
Viendo los procesos dinámicamente con top
Controlando procesos
Interrumpiendo un proceso
Enviando un proceso a segundo plano
Devolviendo un proceso a primer plano
Parando (pausando) un proceso
Señales
Enviando señales a un proceso con kill
Enviando señales a múltiples procesos con killall
Más comandos relacionados con procesos
Resumiendo

Parte 2 – Configuración y el entorno

11 - El entorno
¿Qué se almacena en el entorno?
Examinando el entorno
Algunas variables interesantes
¿Cómo se establece el entorno?
¿Qué hay en un archivo de arranque?
Modificando el entorno
¿Qúe archivos podríamos modificar?
Editores de texto
Usando un editor de texto
¿Por qué son importantes los comentarios?
Activando nuestros cambios
Resumiendo
Para saber más
12 - Una ligera introducción a vi
Por qué deberíamos aprender vi
Un poco de historia
Arrancando y parando vi
Modo de compatibilidad
Modo de edición
Entrar en el modo de inserción
Salvando nuestro trabajo
Moviendo el cursor
Edición básica
Añadiendo texto
Abriendo una línea
Borrando texto
Cortando, copiando y pegando texto
Uniendo líneas
Buscar y reemplazar
Buscando dentro de una línea
Buscando en el archivo completo
Búsqueda y reemplazo global
Editando múltiples archivos
Cambiando entre archivos
Abriendo archivos adicionales para editar
Copiando contenido de un archivo a otro
Insertando un archivo entero dentro de otro
Salvando nuestro trabajo
Resumiendo
Para saber más
13 - Personalizando el Prompt
Anatomía de un prompt
Probando algunos diseños de prompt alternativos
Añadiendo color
Confusión con el Terminal
Moviendo el cursor
Salvando del prompt
Resumiendo
Para saber más

Parte 3 – Tareas comunes y herramientas esenciales

14 - Gestión de paquetes
Sistemas de paquetes
Cómo funciona un sistema de paquetes
Paquetes
Repositorios
Dependencias
Herramientas, de alto y bajo nivel, de paquetes
Tareas comunes en la gestión de paquetes
Encontrar un paquete en un repositorio
Instalando un paquete de un repositorio
Instalando un paquete desde un archivo de paquete
Eliminando un paquete
Actualizando paquetes de un repositorio
Actualizando un paquete desde un archivo de paquete
Listando los paquetes instalados
Determinando si un paquete está instalado
Mostrando información acerca de un paquete instalado
Buscando qué paquete ha instalado un archivo
Resumiendo
El mito de la instalación de software Linux
Para saber más
15- Medios de almacenamiento
Montando y desmontando dispositivos de almacenamiento
Viendo una lista de los sistemas de archivos montados
Por qué es importante desmontar
Determinando los nombres de los dispositivos
Creando un nuevo sistema de archivos
Manipulando particiones con fdisk
Creando un nuevo sistema de archivos con mkfs
Probando y reparando sistemas de archivos
What the fsck?
Formateando disquetes
Moviendo datos directamente a/desde dispositivos
Creando imágenes de CD-ROM
Creando una copia imagen de un CD-ROM
Creando una imagen de una colección de archivos
Un programa con otro nombre…
Escribiendo imágenes de CD-ROM
Montando una imagen ISO directamente
Borrando un CD-ROM regrabable
Escribiendo una imagen
Resumiendo
Para saber más
Punto adicional
16 - Redes
Examinando y monitorizando una red
ping
traceroute
netstat
Transportando archivos por una red
ftp
lftp – Un ftp mejor
wget
Comunicación segura con hosts remotos
ssh
Tunelización con SSH
scp y sftp
¿Un cliente SSH para Windows?
Resumiendo
Para saber más
17 - Buscando archivos
locate – Buscar archivos de forma fácil
¿De donde sale la base de datos de locate?
find – Encontrando archivos de forma difícil
Tests
Operadores
Acciones predefinidas
Acciones definidas por el usuario
Mejorando la eficiencia
xargs
Tratando con nombres de archivo simpáticos
Una vuelta al patio de juegos
Opciones
Resumiendo
Para saber más
18 - Archivado y copias de seguridad
Comprimiendo archivos
gzip
bzip2
No seas un compresor compulsivo
Empaquetando archivos
tar
zip
Sincronizando archivos y directorios
Usando rsync en una red
Resumiendo
Para saber más
19 - Expresiones regulares
¿Qué son las expresiones regulares?
grep
Metacaracteres y literales
El carácter cualquiera
Anclas
Un ayudante de crucigramas
Expresiones entre corchetes y clases de caracteres
Negación
Rangos de caracteres tradicionales
Clases de caracteres POSIX
Volviendo a la secuencia de ordenado tradicional
POSIX básico vs. Expresiones regulares extendidas
POSIX
Alternancia
Cuantificadores
? - Encuentra un elemento cero o una vez
* - Encuentra un elemento cero o más veces
+ - Encuentra un elemento una o más veces
{} - Encuentra un elemento un número específico de veces
Poniendo las expresiones regulares a trabajar
Validando una lista de teléfonos con grep
Encontrando nombres de archivos feos con find
Buscando archivos con locate
Buscando texto con less y vim
Resumiendo
Para saber más
20 - Procesado de texto
Aplicaciones de texto
Documentos
Páginas web
Email
Salida de impresora
Código fuente de programas
Volviendo a visitar antiguos amigos
cat
Texto MS-DOS Vs. Texto Unix
sort
uniq
Reordenando
cut
Expandiendo los tabuladores
paste
join
Comparando texto
comm
diff
patch
Editando sobre la marcha
tr
ROT13: El anillo decodificador no tan secreto
sed
A la gente que le gusta sed también le gusta...
aspell
Resumiendo
Para saber más
Punto Extra
21 - Formateando la salida
Herramientas de formateo simple
nl - Numera líneas
fold - Limita cada línea a una longitud especificada
fmt - Un formateador de texto simple
pr - Formatea texto para imprimir
printf - Formatea e imprime datos
Sistemas de formateo de documentos
groff
Resumiendo
Para saber más
22 -Impresión
Una breve historia de la impresión
Imprimiendo en los tiempos oscuros
Impresoras basadas en caracteres
Impresoras gráficas
Imprimiendo con Linux
Preparando archivos para imprimir
pr - Convierte archivos de texto para imprimir
Enviando un trabajo de impresión a una impresora
lpr - Imprime archivos (Estilo Berkeley)
lp - Imprime archivos (Estilo System V)
Otra opción: a2ps
Monitorizando y controlando trabajos de impresión
lpstat - Muestra el estado del sistema de impresión
lpq - Muestra el estado de la cola de impresión
lprm/cancel - Cancela trabajos de impresión
Resumiendo
Para saber más
23 - Compilando programas
¿Qué es compilar?
¿Todos los programas se compilan?
Compilando un programa en C
Obteniendo el código fuente
Examinando el árbol de código fuente
Construyendo el programa
Instalando el programa
Resumiendo
Para saber más

Parte 4 – Escribiendo scripts de shell

24 -Escribiendo tu primer script
¿Qué son scripts de shell?
Cómo escribir un script de shell
Formato del archivo de script
Permisos de ejecución
Localización del archivo de script
Buenas localizaciones para los scripts
Más trucos de formateado
Nombres largos de opciones
Sangría y continuación de líneas
Configurando vim para escribir scripts
Resumiendo
Para saber más
25 - Comenzando un proyecto
Primera etapa: Documento minimalista
Segunda etapa: Añadiendo algunos datos
Variables y constantes
Asignando valores a variables y constantes
Documentos-aquí
Resumiendo
Para saber más
26 - Diseño de arriba a abajo
Funciones de shell
Variables locales
Mantener los scripts ejecutándose
Funciones shell en tu archivo .bashrc
Resumiendo
Para saber más
27 - Control de flujo: Ramificando con if
if
Estado de la salida
test
Expresiones para archivo
Expresiones para cadenas
Expresiones con enteros
Una versión más moderna de test
(( )) - Diseñado para enteros
Combinando expresiones
La portabilidad es la pesadilla de las mentes pequeñas
Operadores de control: otra forma de ramificar
Resumiendo
Para saber más
28 - Leyendo la entrada del teclado
read - Lee valores de la entrada estándar
Opciones
IFS
No puedes canalizar a read
Validando la entrada
Menús
Resumiendo
Punto extra
Para saber más
29 - Control de flujo: Bucles con while / until
Bucles
while
Salir de un bucle
until
Leyendo archivos con bucles
Resumiendo
Para saber más
30 - Solución de Problemas
Errores sintácticos
Comillas perdidas
Símbolos perdidos o inesperados
Expansiones inesperadas
Errores lógicos
Programación defensiva
Verificando la entrada
El diseño va en función del tiempo
Pruebas
Casos de prueba
Depuración
Encontrando el área del problema
Trazado
Examinando valores durante la ejecución
Resumiendo
Para saber más
31 - Control de Flujo: Ramificando con case
case
Patrones
Realizando múltiples acciones
Resumiendo
Para saber más
32 - Parámetros Posicionales
Accediendo a la línea de comandos
Determinando el número de argumentos
shift - Accediendo a muchos argumentos
Aplicaciones simples
Usando parámetros posicionales con funciones de shell
Manejando parámetros posicionales en masa
Una aplicación más completa
Resumiendo
Para saber más
33 - Control de flujo: Bucles con for
for: Forma tradicional del shell
¿Por qué i?
for: Forma del lenguaje C
Resumiendo
Para saber más
34 - Cadenas y números
Expansión de parámetros
Parámetros básicos
Expansiones para manejar variables vacías
Expansiones que devuelven nombres de variables
Operaciones con cadenas
Conversión de mayúsculas y minúsculas
Evaluación aritmética y expansión
Bases numéricas
Operadores unarios
Aritmética simple
Asignación
Operaciones con bits
Lógica
bc - Un lenguaje de cálculo de precisión arbitraria
Usando bc
Un script de ejemplo
Resumiendo
Punto extra
Para saber más
35 - Arrays
¿Qué son los arrays?
Creando un array
Asignando valores a un array
Accediendo a los elementos de un array
Operaciones con arrays
Mostrando todo el contenido de un array
Determinando el número de elementos de una array
Encontrando los índices usados por un array
Añadiendo elementos al final de un array
Ordenando un array
Borrando un array
Arrays asociativos
Resumiendo
Para saber más
36 - Cosas exóticas
Comandos agrupados y subshells
Sustitución de procesos
Trampas
Archivos temporales
Ejecución asíncrona
wait
Tuberías con nombre
Configurando una tubería con nombre
Usando tuberías con nombre
Resumiendo
Para saber más

lunes, 4 de septiembre de 2017

Para saber más

viernes, 1 de septiembre de 2017

Resumiendo

Bien, hemos completado nuestro viaje. Lo único que queda por hacer ahora es practicar, practicar y practicar. Aunque hemos cubierto bastante terreno en nuestra excursión, apenas hemos arañado la superficie de lo que es la línea de comandos. Todavía quedan miles de programas de línea de comandos pendientes de descubrir y disfrutar. ¡Comienza excavando en /usr/bin y verás!

jueves, 31 de agosto de 2017

Usando tuberías con nombre

Para demostrar cómo funciona la tubería con nombre, necesitaremos dos ventanas de terminal (o alternativamente, dos consolas virtuales). En el primer terminal, introducimos un comando simple y redirigimos su salida a la tubería con nombre:

[me@linuxbox ~]$ ls -l > pipe1

Tras pulsar la tecla Enter, el comando parecerá que se ha colgado. Esto es porque aún no está recibiendo nada desde el otro extremo de la tubería. Cuando esto ocurre, se dice que la tubería está bloqueada. Esta condición desaparecerá una vez que apliquemos un proceso al otro extremo y empiece a leer la entrada desde la tubería. Usando la segunda ventana de terminal, introducimos este comando:

[me@linuxbox ~]$ cat < pipe1

y el listado del directorio producido desde la primera ventana de terminal aparece en el segundo terminal como salida desde el comando cat. El comando ls en el primer terminal se completa con éxito una vez que ya no está bloqueado.

miércoles, 30 de agosto de 2017

Configurando una tubería con nombre

Primero, debemos crear una tubería con nombre. Esto se hace usando el comando mkfifo:

[me@linuxbox ~]$ mkfifo pipe1
[me@linuxbox ~]$ ls -l pipe1
prw-r--r-- 1 me me 0 2009-07-17 06:41 pipe1

Aquí hemos usado mkfifo para crear una tubería con nombre llamada pipe1. Usando ls, examinamos el archivo y vemos que la primera letra en el campo atributos es "p", indicando que es una tubería con nombre.

martes, 29 de agosto de 2017

Tuberías con nombre

En la mayoría de los sistemas tipo Unix, es posible crear un tipo especial de archivo llamado tubería con nombre. Las tuberías con nombre se usan para crear una conexión entre dos procesos y pueden usarse igual que otros tipos de archivos. No son muy populares, pero es bueno conocerlas.

Hay una arquitectura de programación común llamada cliente-servidor, que puede hacer uso de un método de comunicación como las tuberías con nombre, así como de otros tipos de comunicación entre procesos tales como conexiones de red.

El tipo más ampliamente usado de sistema cliente-servidor es, claramente, la comunicación entre un navegador web y un servidor web. El navegador web actúa como cliente, realizando peticiones al servidor y el servidor responde al navegador con páginas web.

Las tuberías con nombre se comportan como archivos, pero en realidad forman buffers "el primero en entrar es el primero en salir" (FIFO - first in first out). Igual que las tuberías normales (sin nombre), los datos entran por un extremo y salen por el otro. Con las tuberías con nombre, es posible configurar algo como esto:

proceso1 > tubería_con_nombre

y

proceso2 < tubería_con_nombre

y se comportará como si fuera:

proceso1 | proceso2

lunes, 28 de agosto de 2017

wait

Primero probaremos el comando wait. Para hacerlo necesitaremos dos scripts, un script padre:

#!/bin/bash

# async-parent : Asynchronous execution demo (parent)

echo "Parent: starting..."

echo "Parent: launching child script..." 
async-child & 
pid=$! 
echo "Parent: child (PID= $pid) launched."

echo "Parent: continuing..." 
sleep 2

echo "Parent: pausing to wait for child to finish..."
wait $pid

echo "Parent: child is finished. Continuing..."
echo "Parent: parent is done. Exiting."

y un script hijo:

#!/bin/bash

# async-child : Asynchronous execution demo (child)

echo "Child: child is running..."
sleep 5
echo "Child: child is done. Exiting."

En este ejemplo, vemos que el script hijo es muy simple. La acción real la realiza el padre. En el script padre, se arranca el script hijo y se envía a segundo plano. El ID de proceso del script hijo se graba asignando a la variable pid el valor del parámetro de shell $!, que siempre contendrá el ID de proceso del último trabajo puesto en segundo plano.

El script padre continúa y luego ejecuta un comando wait con el PID del proceso hijo. Esto hace que el script padre se pause hasta que el script hijo salga, punto en el cual el script padre concluye.

Cuando se ejecutan, los scripts padre e hijo producen la siguiente salida:

[me@linuxbox ~]$ async-parent
Parent: starting...
Parent: launching child script...
Parent: child (PID= 6741) launched.
Parent: continuing...
Child: child is running...
Parent: pausing to wait for child to finish...
Child: child is done. Exiting.
Parent: child is finished. Continuing...
Parent: parent is done. Exiting.

viernes, 25 de agosto de 2017

Ejecución asíncrona

A veces es preferible realizar más de una tarea al mismo tiempo. Hemos visto cómo los sistemas operativos modernos son al menos multitarea incluso multiusuario. Los scripts pueden construirse para comportarse de forma multitarea.

Normalmente, esto implica arrancar un script que, a su vez, arranca uno o más scripts hijos que realizan una tarea adicional mientras que el script padre continúa ejecutándose. Sin embargo, cuando una serie de scripts se ejecutan de esta forma, puede haber problemas en la coordinación entre el script padre y los hijos. Es decir, ¿qué pasa si el padre o el hijo son dependientes el uno del otro, y un script debe esperar a que el otro termine su tarea antes de finalizar la suya propia?

bash tiene un comando integrado para ayudarnos a manejar una ejecución asíncrona como esta. El comando wait hace que un script padre se pause hasta que un proceso especificado (es decir, el script hijo) termine.

jueves, 24 de agosto de 2017

Archivos temporales

Una razón por la que los gestores de señales se incluyen en los scripts es para eliminar los archivos temporales que el script pueda crear para manejar resultados intermedios durante su ejecución. Hay algo artístico en la denominación de los archivos temporales. Tradicionalmente, los programas en sistemas tipo Unix crean sus archivos temporales en el directorio /tmp, un directorio compartido creado para tales archivos. Sin embargo, como el directorio está compartido, esto conlleva algunos problemas de seguridad, particularmente para programas que se ejecutan con privilegios de superusuario. Mas allá del paso obvio de establecer permisos apropiados para los archivos expuestos a todos los usuarios del sistema, es importante dar a los archivos temporales nombres no predecibles. Esto evita un exploit conocido como temp race attack. Una forma de crear un nombre no predecible (pero descriptivo) es hacer algo como esto:

archivotemporal=/tmp/$(nombrebase $0).$$.$RANDOM

Esto creará un nombre de archivo consistente en el nombre del programa, seguido por su ID de proceso (PID), seguido por un entero aleatorio. Fíjate, sin embargo, que la variable de shell $RANDOM solo devuelve un valor del rango 1-32767, que no es un rango muy grande en términos informáticos, por lo que una única instancia no es suficiente para vencer a un posible atacante.

Una forma mejor es usar el programa mktemp (no confundir con la función mktemp de la biblioteca estándar) para crear y nombrar el archivo temporal. El programa mktemp acepta una plantilla como argumento que se usa para construir el nombre del archivo. La plantilla debe incluir una serie de caracteres "X", que se reemplazan con un número correspondiente de letras y números aleatorios. Cuanto más larga sea la serie de caracteres "X", más larga será la serie de caracteres aleatorios. Aquí tenemos un ejemplo:

archivotemporal=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

Esto crea un archivo temporal y asigna su nombre a la variable tempfile. Los caracteres "X" en la plantilla se reemplazan con letras y números aleatorios de forma que el nombre del archivo final (que, en este ejemplo, también incluye el valor expandido del parámetro especial $$ para obtener el PID) debería ser algo así:

/tmp/foobar.6593.UOZuvM6654

Para scripts que se ejecutan por usuarios normales, sería prudente evitar el uso del directorio /tmp y crear un directorio para archivos temporales dentro del directorio home del usuario, con una línea de código como esta:

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp

miércoles, 23 de agosto de 2017

Trampas

En el Capítulo 10, vimos cómo los programas pueden responder a las señales. También podemos añadir esta capacidad a nuestros scripts. Aunque los scripts que hemos escrito hasta ahora no han necesitado esta capacidad (porque tienen tiempos de ejecución muy cortos, y no crean archivos temporales), los scripts más largos y complicados pueden beneficiarse de tener una rutina de manejo de señales.

Cuando diseñamos un script largo y complicado, es importante considerar qué ocurre si el usuario cierra la sesión o apaga el ordenador mientras el script se está ejecutando. Cuando ocurre un evento como este, debe enviarse una señal a todos los procesos afectados. En respuesta, los programas que representan estos procesos pueden realizar acciones para asegurar una terminación apropiada y ordenada del programa. Digamos, por ejemplo, que hemos escrito un script que crea un archivo temporal durante su ejecución. En nombre del buen diseño, habríamos hecho que el script borre el archivo cuando el script termine su trabajo. También sería inteligente hacer que el script borre el archivo si recibe una señal indicando que el programa va a terminar prematuramente.

bash ofrece un mecanismo para este propósito conocido como trampa. Las trampas se implementan con el comando integrado, apropiadamente denominado, trap. trap usa la siguiente sintaxis:

trap argumento señal [señal...]

donde argumento es una cadena que se leerá y tratará como un comando y señal es la especificación de una señal que pone en funcionamiento la ejecución del comando interpretado.

Aquí tenemos un ejemplo simple:

#!/bin/bash

# trap-demo : simple signal handling demo

trap "echo 'I am ignoring you.'" SIGINT SIGTERM

for i in {1..5}; do
    echo "Iteration $i of 5"
    sleep 5
done

Este script define una trampa que ejecutará un comando echo cada vez que recibe la señal SIGINT o SIGTERM mientras el script se está ejecutando. La ejecución del programa aparece así cuando el usuario intenta detener el script presionando Ctrl-c:

[me@linuxbox ~]$ trap-demo
Iteration 1 of 5
Iteration 2 of 5
I am ignoring you.
Iteration 3 of 5
I am ignoring you.
Iteration 4 of 5
Iteration 5 of 5

Como podemos ver, cada vez que el usuario intenta interrumpir el programa, se muestra el mensaje en su lugar.

Construir una cadena para formar una secuencia útil de comandos puede ser complicado, por lo que es una práctica habitual especificar una función de shell como comando. En este ejemplo, se especifica una función de shell separada para manejar cada señal:

#!/bin/bash

# trap-demo2 : simple signal handling demo

exit_on_signal_SIGINT () {
    echo "Script interrupted." 2>&1
    exit 0
}

exit_on_signal_SIGTERM () {
    echo "Script terminated." 2>&1
    exit 0
}

trap exit_on_signal_SIGINT SIGINT
trap exit_on_signal_SIGTERM SIGTERM

for i in {1..5}; do
    echo "Iteration $i of 5"
    sleep 5
done

Este script presenta dos comandos trap, uno para cada señal. Cada trampa, a su vez, especifica una función de shell a ejecutar cuando se recibe una señal en particular. Fíjate en la inclusión de un comando exit en cada una de las funciones de manejo de señales. Sin un exit, el script continuaría tras completar la función.

Cuando el usuario presione Ctrl-c durante la ejecución de este script, el resultado aparece así:

[me@linuxbox ~]$ trap-demo2
Iteration 1 of 5
Iteration 2 of 5
Script interrupted.