SlideShare una empresa de Scribd logo
1 de 62
Descargar para leer sin conexión
1

La shell bash

Capítulo 1 Introducción a Bash
Conceptos clave
•
•
•
•

La shell por defecto en Red Hat Enterprise Linux es la shell bash.
La shell bash se puede utilizar de modo interactivo o como un lenguaje de
escritura de gran alcance.
Tras el arranque, bash ejecuta comandos hallados en el archivo ~/.bashrc,
permitiéndole a los usuarios personalizar su shell.
La shell bash guarda el historial de las líneas de comando ejecutadas. La líneas
de comando se pueden recuperar desde el historial mediante varias expansiones
de historial que comienzan por "!".

La shell bash
En Linux, la shell es el programa más utilizado. La shell es lo que usted ve cuando
inicia sesión o cuando abre una terminal y lo que más usa para iniciar cada comando.
Aunque hay una variedad de shells disponibles, todas siguen la misma conducta básica:
escuchar los comandos del usuario, iniciar procesos como se especifica en los comandos
e informar los resultados al usuario. La shell más utilizada en Linux es la shell bash, la
cual es la shell por defecto en Red Hat Enterprise Linux.
La shell bash no sólo es de fácil uso para tareas sencillas, sino también tiene
capacidades de gran alcance para facilitar tareas complejas o incluso hacerlas posibles.
Esta eficacia trae consigo complejidad, solo basta con dar un vistazo a la página bash
del manual (que tiene mas de 4.500 líneas) para convencerse. Este cuaderno presentará
muchas de estas capacidades de gran alcance.
Shells interactivas vs. Scripts de shell
La shell bash está diseñada para ser eficaz para dos tipos diferentes de uso. Usted ya
está familiarizado con el uso del comando bash como una shell interactiva. Muchas de
estas características de bash permiten a las personas escribir comandos de una manera
más fácil y eficaz y gran parte de este cuaderno se enfocará en estas habilidades.
La shell bash también está diseñada para ser un lenguaje de escritura de gran alcance.
Los scripts de la shell bash son programas pequeños escritos mediante la misma sintaxis
que se utiliza en la línea de comandos. Los scripts de shell permiten a los usuarios
automatizar las acciones repetidas al combinar una serie de comandos. A diferencia de
las shells interactivas, los scripts de shell suelen ejecutar una serie de comandos de
modo no interactivo y muchas de estas características de la shell bash proveen una
programación lógica (tales como ramas y bucles) para escribir scripts sofisticados. Al
final de este cuaderno encontrará una introducción a la escritura de shell.
2

La shell bash
Al continuar a través de este cuaderno, trate de tener en la mente estos dos usos
diferentes de la shell bash. Algunas características de bash, tales como el historial de
comandos, que pronto veremos, son casi inútiles en los scripts de shell. Otros rasgos,
tales como la sustitución aritmética, pueden no parecer út¡les en la línea de comandos,
pero pueden ser útiles en un script de shell. Si la utilidad de una característica de un
bash no es de inmediato obvia, trate de verla en otro contexto.
Shells de inicio
En la práctica, los usuarios a veces necesitan iniciar una shell de modo manual. Cada
vez que alguien inicie sesión o abra una terminal, una shell se inicia automáticamente.
Sin embargo, a veces los usuarios desearían ejecutar una shell diferente u otra instancia
de la misma shell. Dado que la shell es sólo "otro programa", nuevas shells pueden
iniciarse desde la shell existente. La nueva shell se denomina subshell de la shell
original. Cuando se sale de la subshell, el control vuelve a la shell original. En el
siguiente ejemplo, madonna inicia una subshell bash, lista los procesos desde dentro de
ésta para confirmar que las dos shells se están ejecutando y luego sale de la subshell.
[madonna@station madonna]$ bash
[madonna@station madonna]$ ps
PID TTY
TIME CMD
9750 pts/5
00:00:00 bash
9786 pts/5
00:00:00 bash
9814 pts/5
00:00:00 ps
[madonna@station madonna]$ exit
exit
[madonna@station madonna]$

Cuando inicia una subshell bash, las diferencias aparentes entre la subshell y la shell
padre son mínimas y se debe tener cuidado de seguir el rastro de la shell en la que se
encuentra.
El archivo ~/.bashrc
Como parte de su inicialización, la shell bash buscará en el directorio de inicio del
usuario un archivo titulado .bashrc. El archivo se emplea para personalizar la shell
bash. Cuando la shell inicia, los comandos listados en el archivo se ejecutan como si
fueran escritos en la línea de comandos. Técnicamente, la shell bash "lee" el archivo.
Los conceptos relacionados con la lectura de archivos y la inicialización de shell se
tratarán en detalle más adelante. Aquí, presentaremos rápidamente este sólo archivo
para poder hacer uso de él en ejercicios posteriores.
A continuación, madonna edita su archivo ~/.bashrc agregándole el comando cal, para
que tras el arranque la shell bash se presente un calendario del mes actual.
[madonna@station madonna]$ nano .bashrc
... (madonna appends a single line containing the command "cal") ...
[madonna@station madonna]$ cat .bashrc
3

La shell bash
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
cal

La usuaria madonna agregó esta única línea. Las líneas restantes se encuentran en
un archivo por defecto ~/.bashrc de un usuario.
Ahora, cada vez que madonna inicia una shell bash (por ejemplo, iniciando en una
consola virtual o abriendo otra ventana de terminal), se presenta un calendario.
[madonna@station madonna]$ bash
August 2003
Su Mo Tu We Th Fr Sa
-*//
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
[madonna@station madonna]$ exit

Introducir Comandos
Las shells interactivas repiten el ciclo de escuchar una línea de comandos, evalúan el
comando solicitado, realizan todas las acciones solicitadas y muestran los resultados. La
shell escucha al teclado de entrada y emplea la tecla de ENTER para reconocer el final
de la entrada como en la siguiente ejecución del comando echo.
[madonna@station madonna]$ echo "hello world"
hello world

Historial de comandos
Como conveniencia para los usuarios de shells interactivas, el comando shell bash
mantiene el historial de cada uno de los comandos escritos por el usuario y ofrece una
variedad de formas para hacer que los comandos desde este historial estén a su alcance.
La forma más fácil de ver el historial actual es mediante el comandohistory.
[blondie@station blondie]$ history
1 ls -l /home/
2 ls -ln /home/
3 exit
4 exit
5 id
...
167 mv rhyme stuff/
4

La shell bash
168
169
170
171
172

ls -Rli
exit
exit
history

Como se muestra, el comando history entrega un historial de los comandos previamente
escritos, con cada entrada precedida por un "número de historial". El comando history
va hasta el final de la lista. Desde la línea de comandos, las teclas de dirección
ARRIBA y ABAJO atraviesan pronto la lista de arriba a abajo, mientras que las teclas
de dirección IZQUIERDA y DERECHA moverán el cursor para permitir al usuario
editar un comando dado. Por ejemplo, si blondie quisiera luego ejecutar el comando ls
-li, podría pulsar la tecla ARRIBA 5 veces y su intérprete de comandos llenaría con el
comando ls -Rli. Podría entonces pulsar dos veces la tecla de dirección IZQUIERDA
y RETROCESO para suprimir R de la línea de comandos seguido por la tecla ENTER.
Mediante las teclas de flecha, los usuarios pueden rápidamente revisar, editar y ejecutar
comandos tecleados anteriormente.
Sustitución de historial
Como una alternativa a las teclas de dirección, la shell bash también realiza "sustitución
de historial", la cual se desencadena por el signo de exclamación. El siguiente cuadro
resume la sintaxis de sustitución de historial más utilizada.
Table 1. Sustitución de historial bash
Sustitución
Sintaxis
!!
Comando anterior
!n

Comando número n

!-n

El comando más reciente n

!cmd

El comando más reciente que comienza por cmd

A manera de ejemplo de la sintaxis anterior, analice la siguiente salida (abreviada)
cuando blondie ejecuta el comando history.
[blondie@station blondie]$ history
...
161 ls
162 ls -il
163 ln rhyme hard_link
164 ls -il
165 chmod 660 rhyme
166 ls -il
167 mv rhyme stuff/
168 ls -Rli
169 exit
170
171 exit
172 history
5

La shell bash
El siguiente cuadro lista lo que blondie escribiría en la línea de comandos y el comando
resultante que ejecutaría.
Línea de comandos Comando resultante
!!

historial

!165

chmod 660 rhyme

!-5

ls -Rli

!mv

mv rhyme stuff/

Conservar el historial entre sesiones
No sólo el comando shell bash mantiene un historial de comandos dentro de una sesión,
sino que también conserva los historiales de comandos entre sesiones. Cuando la shell
bash sale, entrega el historial actual del comando dentro de un archivo llamado
.bash_history en un directorio de inicio del usuario. Tras el arranque, la shell
inicializa el historial de comandos desde el contenido de este archivo.
¿Qué repercusión tienen estas shells interactivas múltiples (pertenecientes a un mismo
usuario) al ejecutar al mismo tiempo? Puesto que el historial solo se ha guardado en el
disco cuando la shell sale, los comandos ejecutados en un proceso bash no están
disponibles en el historial de comandos de un procesobash ejecutado simultáneamente.
Además, la última shell al salir sobrescribirá las historias de las shells que salieron
anteriormente.
Si está establecido así, las siguientes variables configuran los detalles de cómo se
guarda el historial de comandos.
Table 1. Variables del historial de comandos de shell bash
Variable

Valor
predeterminado

Efectos

HISTFILE

~/.bash_history

El archivo en el cual el historial de comandos se
guarda al salir y desde el cual se inicializa al
arrancar.

HISTFILESIZE

1000

El archivo HISTFILE se truncará a este tamaño en
el arranque.

HISTSIZE

1000

El número máximo de comandos que se
escribrirán al salir en el archivoHISTFILE.

Trucos del historial de comandos
La shell bash ofrece muy pocas técnicas para acceder previamente los comandos
tecleados (o elementos del mismo).
6

La shell bash
ESC-. y ALT-.
El último símbolo de la línea de comandos tecleados anteriormente puede
recuperarse con cualquiera de las dos secuencias de teclas mencionadas
anteriormente. Una vez aprendido, este truquito suele ser muy útil. El último
simbolo de un comando suele representar el objeto que alguien está
manipulando. Por ejemplo, alguien podría hacer un directorio y enseguida
ejecutar cd en éste o editar un archivo e inmediatamente querer utilizar chmod
para cambiar sus permisos. Si la secuencia clave se repite, la shell bash
continuará el ciclo a través de los últimos símbolos de las primeras líneas de
comando.
CTRL-R
Esta secuencia clave imita a !cmd en espíritu. El texto tecleado después de
CTRL-R coincide con los comandos tecleados anteriormente con la ventaja de
que las líneas de comandos coincidentes se ven de modo inmediato al teclear el
texto. Usted también tiene la oportunidad de editar la línea recuperada
(utilizando las teclas de dirección IZQUIERDA y DERECHA u otros golpes
de teclado de edición de líneas de comando) antes de ejecutar el comando.
fc
El comando fc permite a los usuarios "arreglar" el comando escrito
anteriormente al abrir el editor por defecto del usuario (por defecto vi) con el
comando anterior escrito como texto. Tras salir del edtor (presumiblemente
después de editar de alguna forma el comando), el nuevo texto se ejecutará de
inmediato. Para aquellos expertos en salir del editor rápidamente, el comando es
muy útil.
Ejemplos
Uso del historial de comandos para acortar el ciclo "editar/compilar/ejecutar"
Con frecuencia, los programadores de lenguajes compilados tales como C suelen
hallarse en un ciclo repetitivo: editar un archivo, compilarlo y luego ejecutar el
programa. A continuación, madonna edita un archivo que contiene un programa
pequeño C y luego lo compila con el compilador C gcc. Después de ejecutar el
programa, decide hacer algunos cambios. Hace entonces uso del historial de comandos
para agilizar el proceso.
[madonna@station madonna]$ nano hello.c
[madonna@station madonna]$ cat hello.c
#include "stdio.h"
int main(void)
{
printf("hello worldn");
return 0;
7

La shell bash
}
[madonna@station madonna]$ gcc -o hello hello.c
[madonna@station madonna]$ ./hello
hello world
[madonna@station madonna]$ !n
nano hello.c
(... madonna edits the file, replacing the string "hello world"
with "hello dolly" ...)
[madonna@station madonna]$ !c
cat hello.c
#include "stdio.h"
int main(void)
{
printf("hello dollyn");
return 0;
}
[madonna@station madonna]$ !g
gcc -o hello hello.c
[madonna@station madonna]$ !.
./hello
hello dolly

Observe que la shell bash imprime el comando seleccionado desde el historial de
madonna antes de ejecutar el comando.
Uso de ESC.
Ahora madonna quisiera crear un subdirectorio bin, establece sus permisos para que
sólo ella pueda acceder a éste y mover su archivo ejecutable hello en él. Usa la
secuencia de teclas ESC-. para agilizar el proceso.
[madonna@station
[madonna@station
[madonna@station
[madonna@station
hello

madonna]$
madonna]$
madonna]$
madonna]$

mkdir bin
chmod 700 <ESC-.>
mv hello <ESC-.>
ls <ESC-.>

Quizas no es el ejemplo más interesante porque bin es un directorio muy pequeño para
teclear de todas maneras. Sin embargo, si hubiera sido el directorio
/usr/lib/perl5/ven or_perl/5.8.0/HTML/, los golpes de teclado grabados serían
impresionantes.
Inhibición del historial de comandos
Madonna es desconfiada y preferiría que su historial de comandos fuera almacenado en
el disco al salir de la shell. Suprime su archivo del historial y crea un enlace blando con
el mismo nombre que apunta al nodo de dispositivo /dev/null.
[madonna@station madonna]$ rm .bash_history
8

La shell bash
[madonna@station madonna]$ ln -s /dev/null .bash_history
[madonna@station madonna]$ ls -l .bash_history
lrwxrwxrwx
1 madonna madonna
9 Aug 26 16:35 .bash_history
-> /dev/null
[madonna@station madonna]$ cat .bash_history
[madonna@station madonna]$

Madonna ahora puede usar el historial de comandos de bash para recuperar los
comandos utilizados en la shell actual, pero ningún historial de comandos se almacenará
entre las instancias de shell.
Ejercicios en línea
Lab Exercise
Objetivo: Personalizar su archivo ~/.bashrc para mantener un registro de
cuándo se inician las shells.
Estimated Time: 10 mins.
Especificaciones
1. Use un editor de texto para modificar el archivo .bashrc desde su directorio de
inicio, agregando la siguiente línea al final del archivo.
2.

date >> .bash_timestamps

3. Observe el archivo .bash_timestamps, y confirme si se agrega una nueva
marca de tiempo cada vez que inicia una nueva shell bash.
4. De nuevo, mediante un editor de texto, agregue una línea de comentario a su
archivo .bashrc que describa brevemente por qué el comando de fecha fue
agregado e incluya su nombre de usuario como la persona que hizo la
modificación.
Deliverables
A title
Question 1

1. En su directorio de inicio, un .bashrc modificado que agregue una marca de
tiempo al archivo .bash_timestamps cada vez que se inicie una shell bash.
2. El archivo .bashrc debe también contener una línea de comentario que incluya
su nombre de usuario.
9

La shell bash
Capítulo 2 Listas de comandos y scripts
Conceptos clave
•
•
•
•

Comandos múltiples se pueden separar con un ;.
Tras la salida, cada comando devuelve un entero a su padre denominado valor de
retorno.
La variable de shell $? se expande al valor de retorno de un comando ejecutado
previamente.
&& y || separan condicionalmentecomandos múltiples.

Ejecución de comandos múltiples
La shell bash permite a los usuarios unir comandos múltiples en una sola línea de
comandos separando los comandos con un ;. (en inglés es igual; las frases
independientes se separan con un punto y coma). Veamos un ejemplo:
[elvis@station
applnk
desktop-menus
Xmodmap
fs
Xresources
gdm
xserver
lbxproxy
[elvis@station

elvis]$ cd /etc/X11; ls
prefdm
sysconfig
proxymngr
twm

xorg.conf.backup
xorg.conf.wbx

rstart

X

xorg.conf.works

serverconfig

xdm

XftConfig.README-OBSOLETE

starthere
X11]$

xorg.conf

xinit

xkb

xsm

El efecto es idéntico al escribir comandos en líneas separadas.
[elvis@station
[elvis@station
applnk
desktop-menus
Xmodmap
fs
Xresources
gdm
xserver
lbxproxy
[elvis@station

elvis]$ cd /etc/X11
X11]$ ls
prefdm
sysconfig
proxymngr
twm

xorg.conf.backup
xorg.conf.wbx

rstart

X

xorg.conf.works

serverconfig

xdm

XftConfig.README-OBSOLETE

starthere
X11]$

xorg.conf

xinit

xkb

xsm

La única diferencia entre los dos enfoques es que no se tiene la oportunidad de examinar
el efecto del primer comando antes de que el segundo comando se ejecute. Muy pocas
veces existe la necesidad real de ejecutar comandos múltiples desde una solo línea de
comandos, pero suele ser conveniente combinar los comandos.
Ejecución de comandos en una subshell
10

La shell bash
La shell bash permite a los usuarios la fácil ejecución de comandos en una subshell,
delimitando el comando entre paréntesis. Considere el siguiente ejemplo:
[elvis@station
applnk
desktop-menus
Xmodmap
fs
Xresources
gdm
xserver
lbxproxy
[elvis@station

elvis]$ (cd /etc/X11; ls)
prefdm
sysconfig
xorg.conf.backup
proxymngr
twm
xorg.conf.wbx
rstart

X

xorg.conf.works

serverconfig

xdm

XftConfig.README-OBSOLETE

starthere
elvis]$

xorg.conf

xkb

xinit

xsm

A primera vista, la conducta parece idéntica a la del ejemplo anterior. Una mirada más
de cerca revela una diferencia sutil pero importante. En el primer ejemplo, cuando los
comandos se separan apenas por un punto y coma, los comandos se ejecutan en la shell
actual. El intérprete de comandos de bash revela que, después de ejecutados los
comandos, la shell del directorio de trabajo actual ha cambiado a /etc/X11 como
resultado del comando cd.
En el ejemplo anterior, al delimitar los comandos entre paréntesis, el directorio de shell
actual no cambia. Cuando bash encuentra un paréntesis en la línea de comandos, éste
genera un nuevo proceso hijobash (llamado subshell) y ejecuta los comandos dentro de
la subshell. Después de ejecutarlos, la subshell sale y el usuario queda en la shell
original (shell sin cambios). El efecto es parecido a la siguiente secuencia de comandos.
[elvis@station
[elvis@station
applnk
desktop-menus
Xmodmap
fs
Xresources
gdm
xserver
lbxproxy
[elvis@station
exit
[elvis@station

elvis]$ bash
elvis]$ cd /etc/X11; ls
prefdm
sysconfig
proxymngr
twm

xorg.conf.backup
xorg.conf.wbx

rstart

X

xorg.conf.works

serverconfig

xdm

XftConfig.README-OBSOLETE

starthere
X11]$ exit

xorg.conf

xinit

xkb

xsm

elvis]$

La subshell se inicia manualmente al ejecutar el comando bash.
Los comandos se ejecutan ahora en la subshell.
Al terminar, se sale de la subshell.
Ahora que elvis está de nuevo en su shell original, las modificaciones en la subshell
(tales como el cambio en el directorio de trabajo actual) han quedado atrás.
¿Por qué podría alguien desear ejecutar un comando en una subshell? Las subshells se
utilizan para evitar efectos secundarios. Lo que suceda en la subshell no debería tener
efecto en el entorno original de la shell (como en inglés, lo que está entre paréntesis no
debe cambiar la frase que lo rodea).
11

La shell bash
Introducción a los scripts de shell
La clave para usar Red Hat Enterprise Linux de modo efectivo es la automatización. Un
buen administrador de Linux debe ser en realidad extremadamente perezoso cuando se
trata de hacer algo aburridor o repetitivo. Las secciones anteriores ilustraron la manera
de encadenar comandos para ejecutar de modo consecutivo o simultáneo en lugar de
esperar a que el comando termine antes de teclear el próximo. También le introdujeron a
las características del historial de bash y le mostraron cómo referirse a comandos
tecleados previamente para que sólo tenga que escribirlos una vez.
Sin embargo, aún falta una parte importante de la caja de herramientas del
administrador del sistema: la escritura de scripts. Un script, en su forma más simple, es
un texto con una lista de comandos en él. Los comandos se envían a través de un
programa específico llamado intérprete, el cual ejecuta un comando a la vez. Este
intérprete suele ser la shell bash (conocida como /bin/bash o /bin/sh) y cada
comando es un comando común de Linux. Otros intérpretes permiten utilizar lenguajes
de programación de gran alcance como Perl, Python y Ruby.
Antes de comenzar a escribir sus propios scripts hay algunas cosas importantes que
recordar:
•

•

•

La primera línea de su script debe especificar a qué intérprete enviar las
instrucciones. Esto se hace con una cadena especial llamada "shebang"
(pronunciada "shuh-bang"), la cual se ve así: #!. A la shebang le sigue un
nombre de un intérprete para este script. Así, por ejemplo, para usar bash como
su intérprete usted debería usar #!/bin/sh o #!/bin/bash. La mayoría de los
scripts sólo usan #!/bin/sh. Al referirse al intérprete como #!/bin/bash se
habilitan otras características, pero se limita la compatibilidad del script con los
sistemas antiguos de Unix y rara vez es necesario.
Antes de ejecutar un script, usted debe habilitar el permiso "ejecutable" en él (de
lo contrario, es sólo un archivo de texto). El comando para esto es chmod u+x
<scriptname>. Le otorga (y sólo a usted) permiso para ejecutar este script justo
como usted haría con otro comando. El comando chmod se tratará en detalle
más adelante en esta clase.
Si creó un script llamado foo.sh en su directorio de inicio y justo después
tecleó foo.sh obtendría el mensaje de error "no existe tal directorio o archivo".
Esto se debe a que cuando teclea un comando hay una serie de directorios en
donde Linux busca ese comando. Estos directorios se conocen colectivamente
como su RUTA y, por razones de seguridad, su RUTA nunca incluye el
directorio actual. Para resolver este problema tiene dos alternativas:
1. Usted puede especificar de modo explícito la ubicación del script al
teclear ~/foo.sh o ./foo.sh ("." siempre se refiere al directorio actual).
2. Puede colocar el script en un directorio que sea parte de su RUTA. Los
usuarios que no son root no tienen permiso para colocar archivos en la
mayoría de estos directorios, pero todos los usuarios tienen un bin
personal, al cual pueden escribir en su directorio de inicio. Por lo tanto,
12

La shell bash
si foo.sh fuera movido a ~/bin se podría ejecutar al teclear simplemente
foo.sh en la línea de comandos. Esta es la técnica preferida.
aprenderá más acerca de la RUTA en capítulos siguientes.
Veamos un simple ejemplo. Suponga que usted es un administrador que necesita ver
con frecuencia qué usuarios han iniciado sesión en el sistema. Esta información puede
obtenerse al ejecutar el comando w (sí, eso es todo) pero mientras esto proporciona un
buen resumen de quién ha iniciado sesión, no imprime la hora en la que se tomó esta
instantánea de la actividad del usuario. Otro comando, llamado date imprime la fecha y
hora actual, pero no la información del usuario. Si solo usted pudiera combinar esos dos
comandos...
Suponga que creó un script llamado wdate.sh en su directorio personal bin:
[student@station ~]$ cat ~/bin/wdate.sh
#!/bin/sh
date
w
[student@station ~]$ chmod u+x ~/bin/wdate.sh
[student@station ~]$ wdate.sh
Thu Jul 14 12:13:54 PDT 2005
12:13:54 up 2 days, 12:50, 8 users,
USER
TTY
FROM
student_a
tty1
student
tty2
:0.0
/bin/sh/home/student/bin/wdate.sh

load average: 0.35, 0.27, 0.18
LOGIN@
IDLE
JCPU
PCPU WHAT
Mon23
?xdm? 2:43m 3.06s /bin/bash
Tue17
0.00s 2.19s 0.00s

[student@station ~]$

Observe que el script había sido colocado en ~/bin y era ejecutable antes de ejecutarse
como un comando normal. Al ejecutar date seguido por w, ¡nos da dos comandos por el
precio de uno! Obviamente, este script podría luego modificarse para ejecutar un
número arbitrario de comandos seguidos. De hecho, los scripts pueden ser mucho más
eficaces que apenas una lista de comandos y pueden ser programas complejos en su
propio derecho. El material complementario de esta lección describe técnicas avanzadas
para scripts y pueden habilitarse a discreción de su instructor. Por ahora, concéntrese en
dominar los scripts básicos como una valiosa técnica de almacenamiento. La regla de
oro del administrador es que si usted tiene que hacer una tarea más de dos veces,¡haga
un script!
Valores de retorno
Cada proceso en Linux tiene un ciclo de vida. Todos los procesos comienzan a solicitud
de otro proceso (a menudo shell). El proceso solicitado se denomina padre, y el proceso
recién nacido el hijo. El proceso hijo suele realizar sus deberes (incluyendo generar sus
propios hijos), y luego elige morir. Un proceso de salida deja atrás una pequeña parte de
información cuando muere, llamado el valor de retorno del proceso o estatus de salida.
El proceso padre es responsable de reunir los valores de retorno de los hijos muertos.
13

La shell bash
Los valores de retorno vienen en forma de enteros los cuales van de 0 a 255. Los
programas pueden escoger líbremente el valor al salir [1]. A menudo, lo que significan
las implicaciones por valores de retorno son parte de una interfaz de un programa bien
definido y están documentadas en la página man del programa, (si no está familiarizado
con el comandodiff, la sección de "DIAGNÓSTICO" de su página del manual ofrece un
ejemplo). Una convención de Linux (y Unix) es que un programa devuelve en 0 para
implicar "éxito" en lo que estaba intentando hacer, y un valor de retorno de no cero que
implica algun tipo de error.
La shell bash almacena el valor de retorno del comando ejecutado anteriormente en una
variable especial llamada ?. Infortunadamente, no hemos descrito aún todas las
variables de shell (eso sigue luego), pero observemos que el valor de esta variable (por
ejemplo, el valor de retorno del programa ejecutado antes), puede examinarse con el
comando echo $?.
En el siguiente ejemplo, el comando ls se utiliza para examinar los permisos del archivo
/etc/passwd. Dado que el comando "funciona", el comando ls devuelve un valor de
retorno de 0.
[elvis@station elvis]$ ls -l /etc/passwd
-rw-r--r-1 root
root
3694 Aug 15 16:26 /etc/passwd
[elvis@station elvis]$ echo $?
0

En contraste, los siguientes ejemplos muestran cómo responde el comando ls al listar un
archivo que no existe.
[elvis@station elvis]$ ls -l /etc/password
ls: /etc/password: No such file or directory
[elvis@station elvis]$ echo $?
1

Dado que el comando "no funcionó", devolvió un valor de retorno de 1. Devolver un 0
de éxito y un 1 cuando se presenta cualquier tipo de error, es una conducta normal. Si
una página man del programa no menciona otra cosa, generalmente se puede asumir
esta conducta.
Ejecución de comandos múltiples de modo condicional
La shell bash usa &&y || para unir dos comandos de modo condicional. Cuando los
comandos se unen de este modo, el primero siempre se ejecutará. El segundo comando
puede que se ejecute o no dependiendo del valor de retorno del primer comando. Por
ejemplo, un usuario puede desear crear un directorio y luego mover un nuevo archivo
dentro de ese directorio. Si la creación del directorio fracasa, entónces no hay razón para
mover el archivo. Los dos comandos pueden acoplarse de la siguiente forma.
[elvis@station elvis]$ echo "one two three" > numbers.txt
[elvis@station elvis]$ mkdir /tmp/boring && mv numbers.txt /tmp/boring
[elvis@station elvis]$ ls
14

La shell bash
Al acoplar los dos comandos con &&, el segundo comando sólo ejecutará el primer
comando que tuvo éxito (por ejemplo, tuvo un valor de retorno de 0). Esto es similar a
la operación "and" que se encuentra en varios lenguajes de programación. En el ejemplo
anterior, el comando mkdir tuvo éxito y luego el archivo se movió. ¿Qué sucedería si el
comando mkdir fracasara?
[elvis@station elvis]$ echo "one two three five seven eleven" >
primes.txt
[elvis@station elvis]$ mkdir /tmp/mostly/boring && mv primes.txt
/tmp/mostly/boring
mkdir: cannot create directory `/tmp/mostly/boring': No such file or
directory
[elvis@station elvis]$ ls
primes.txt

Dado que el comando mkdir fracasó (el directorio /tmp/mostly no existá, por lo tanto
el directorio /tmp/mostly/boring no se pudo crear), bash no trató de ejecutar el
comando mv.
Igualmente, los comandos múltiples pueden combinarse con ||. En este caso, bash
ejecutará el segundo comando sólo si el primer comando "fracasa"(tiene un valor de
retorno diferente a cero). Esto es igual al operador "or" que se encuentra en lenguajes de
programación. En el siguiente ejemplo, elvis intenta cambiar los permisos en un
archivo. Si el comando fracasa, un mensaje para ese efecto se imprime en la pantalla.
[elvis@station elvis]$ chmod 600 /tmp/boring/numbers.txt || echo
"chmod failed."
[elvis@station elvis]$ chmod 600 /tmp/mostly/boring/primes.txt || echo
"chmod failed"
chmod: failed to get attributes of `/tmp/mostly/boring/primes.txt': No
such file or directory
chmod failed

En el primer caso, el comando chmod tuvo éxito, y no se imprimió ningún mensaje. En
el segundo caso, el comando chmod fracasó (porque el archivo no existía) y apareció el
mensaje "chmod failed" (aparte del mensaje de error estándar de chmod).
Ejemplos
Echoing $? twice
El usuario elvis acaba de aprender sobre los valores de retorno, y está examinando los
valores de retorno de varios comandos. Después de ejecutar (sin éxito) el comando ls,
encuentra que, como era de esperar, la variable de bash ? contiene 1. Al examinar la
variable otra vez, se da cuenta que ahora contiene un 0. ¿Qué hizo cambiar el valor?
[elvis@station elvis]$ ls -l /etc/password
ls: /etc/password: No such file or directory
[elvis@station elvis]$ echo $?
1
[elvis@station elvis]$ echo $?
15

La shell bash
0

Recuerde que la variable de bash ? contiene el valor de retorno de los comandos
ejecutados más recientemente. En el primer caso, éste contenía el valor de retorno (sin
éxito) del comando ls. En el segundo caso, éste contenía el valor de retorno del
comando echo (con éxito).
Visualización de recordatorios
El usuario ahora quiere desarrollar un esquema en donde pueda dejar recordatorios y
que automáticamente aparezcan al iniciar una shell. Crea un archivo en el directorio de
inicio llamado reminders con el texto brush your teeth y agrega la siguiente línea a
su archivo ~/.bashrc.
cat /home/elvis/reminders

Luego prueba su configuración de modo manual iniciando una nueva shell bash.
[elvis@station elvis]$ echo "brush your teeth" > reminders
[elvis@station elvis]$ nano .bashrc
[elvis@station elvis]$ cat .bashrc
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
cat reminders
[elvis@station elvis]$ bash
brush your teeth
[elvis@station elvis]$ exit
exit
[elvis@station elvis]$

Todo parece funcionar bien, hasta que elvis sigue su consejo de limpieza y borra su
archivo reminders. La próxima vez que inicia una shell se encuentra con lo siguiente:
[elvis@station elvis]$ bash
cat: reminders: No such file or directory
[elvis@station elvis]$

Dándose cuenta que le gustaría ejecutar el comando cat sólo si el archivo reminders
existe, edita la línea que agregó a su archivo .bashrc con lo siguiente:
ls reminders > /dev/null && cat reminders
16

La shell bash
Ahora el comando cat sólo se ejecutará si el comando ls tiene éxito, porque el archivo
reminders existe, (¿hay una mejor forma de hacer esto? Sí, pero aún no hemos
aprendido lo suficiente para hacerlo.)
Ejercicios en línea
Lab Exercise
Objetivo: Ejecutar comandos dentro de una subshell.
Estimated Time: 10 mins.
Especificaciones
1. Agregue una sola línea al final del archivo .bashrc en su directorio de inicio.
La línea debe ejecutar los comandos cd /usr y ls en una sola subshell , (al
ejecutarla, el directorio de trabajo actual de su shell no se afectará.)
Si se implementa correctamente, al iniciar una nueva shell debería ver una salida similar
a la siguiente:
[elvis@station elvis]$ bash
bin
etc
include
lib
dict games kerberos libexec
[elvis@station elvis]$

local
sbin

share
src

tmp
X11R6

Deliverables
A title
Question 1

1. Un archivo ~/.bashrc cuya última línea ejecute los comandos cd /usr y ls en
una sola subshell.

Limpieza
Una vez obtenga la calificación, restaure su archivo ~/.bashrc al estado original.
Capítulo 3 Variable de bash
Conceptos clave
•
•

Las variables de la shell se asignan mediante una sintaxis A=apple.
Las variables se examinan ("desreferencian") con el caracter $ como en echo
$A.
17

La shell bash
•
•
•

En el nivel de kernel, cada proceso tiene una colección de variables de entorno
que los procesos hijos heredan.
El comando export convierte una variable de shell en una variable de entorno.
Los comandos set y env listan las variables de shell y las variables de entorno,
respectivamente.

Conceptos básicos de la variable de shell
La shell bash le permite a los usuarios establecer y hacer referencia a las variables de
shell. Una variable de shell es simplemente un valor con nombre que la shell recuerda.
Las variables de shell se pueden utilizar en comandos y scripts de shell y pueden
también referenciarse en programas como opciones de configuración. Por ejemplo, el
cliente de correo electrónico mutt ejecuta un editor externo al escribir un mensaje. Por
defecto este editor esvi. Sin embargo, antes de ejecutar vi comprobará si una variable
llamadaEDITOR se ha establecido. Si se ha establecido, entonces el comando definido
por EDITOR se utiliza en lugar de vi. La mayoría de los programas que lanzan editores
externos funcionan del mismo modo.
Hay dos tipos de variables de shell: variables locales y variables de entorno. Una
variable local existe solo dentro de la shell en la cual se crea. Las shells hijas heredan
las variables de entorno como cuando se lanza una terminal después de iniciar sesión.
Primero, veremos cómo definir una variable local, luego hablaremos acerca de cómo
definir variables de entorno incluyendo la bash misma.
El configurar las variables locales es bastante sencillo. En el siguiente ejemplo, prince
establecerá la variable A con el valor apple.
[prince@station prince]$ A=apple

Si usted sigue, asegúrese de no dejar ningún espacio a los lados del signo =. Ahora la
shell se "cuelga"a esta asociación por todo el tiempo que exista la shell (o hasta que se
anule explícitamente, ver a continuación). Cada vez que prince quiera usar el valor
"apple", puede usar la variable A en su lugar, iniciando la variable con el signo ($),
como en el comando echo mostrado abajo. Esto se llamadesreferenciar la variable A.
[prince@station prince]$ echo $A
apple

La variable se puede utilizar en cualquier parte de la línea de comandos (o en los scripts
de shell). ¿Qué sucede si prince, en lenguaje colorido, decidiera escribir unas cuantas
líneas acerca de las manzanas (o apples en inglés) y las almacenara en un archivo
llamado ode_to_apple.txt. La siguiente línea podría ayudarlo a empezar:
[prince@station prince]$ echo "Oh, I like them squishy" >>
ode_to_$A.txt
[prince@station prince]$ ls
18

La shell bash
ode_to_apple.txt

Cuando la shell bash examinó la línea de comandos, remplazó $A por apple. Estos son
los conceptos básicos de las variables de shell. Las variables se establecen y se
configuran con una sintaxis VAR=valor y se desreferencian con una sintaxis $VAR.
Detalles de la variable de shell
¿Qué puede utilizarse como nombres de variables? Los nombres de variables pueden ser
cualquier cadena de caracteres alfanuméricos (A-Z, a-z, 0-9), y el guión bajo (_), pero
no pueden comenzar por un número. Las variables de shell distinguen mayúsculas de
minúsculas, como se muestra a continuación.
[prince@station prince]$ B=banana
[prince@station prince]$ echo $B is my favorite fruit
banana is my favorite fruit
[prince@station prince]$ echo $b is my favorite fruit
is my favorite fruit

En el primera impresión en pantalla, $B fue remplazado por el valor banana. ¿Cómo fue
desreferenciado $b? Si se le pide a la shell desreferenciar una variable no establecida,
ésta remplaza la referencia de la variable con una cadena vacía (en otras palabras, con
nada). Dado que b se considera como una variable diferente a B, y que la variable b
nunca ha sido asignada, la shell remplaza la referencia $b con nada. Por protocolo, las
variables suelen definirse con mayúsculas, pero esto no es más que protocolo.
¿Cuál puede ser el valor de la variable? Cualquier cosa. El truco se presenta en la
asignación. Cuando se asignan las variables, la sintaxis es nombre=valor, sin dejar
espacios. ¿Qué sucedería si prince quisiera que la variable FRUIT apuntara a la frase
mushy bananas?
[prince@station prince]$ FRUIT=mushy bananas
-bash: bananas: command not found

Nos hemos tropezado con una sintaxis avanzada para configurar las variables, es decir
nombre=valor comando, el cual establece la variable name sólo para la ejecución del
comando especificado. La shellbash obedientemente estableció la variable FRUIT en el
valor mushy y fue a ejecutar el comando bananas, con resultados esperables. Pero esto
no es lo importante, lo importante es que si quiere establecer una variable a un valor que
contenga espacios, debe incluir el valor entre comillas.
[prince@station prince]$ FRUIT="mushy bananas"
[prince@station prince]$ echo $FRUIT is my favorite fruit
mushy bananas is my favorite fruit

Con esta modificación, prince obtiene la conducta correcta desde la shell bash, si no la
gramática inglesa correcta.
19

La shell bash
Cuando se desreferencian las variables, el nombre de la variable puede marcarse con
corchetes {}, si es necesario. Por ejemplo, ¿qué sucedería si arriba, prince hubiera
querido guardar su poema dentro de un archivo llamado apple_ode.txt? El ensaya el
primer método obvio, en el mismo directorio como se muestra arriba.
[prince@station prince]$ echo $A
apple
[prince@station prince]$ echo "Oh, I like them squishy" > $A_ode.txt
[prince@station prince]$ ls
ode_to_apple.txt

¿Dónde está el archivo apple_ode.txt? Un par de cosas han conspirado contra prince.
Primero, la shell bash desreferenció el nombre correcto de variable, pero no el que
prince quería. ¿De qué puede estar compuesta una variable? De caracteres
alfanuméricos y minúsculas. La shell bash apuntó a la variable (sin inicializar) A_ode (a
nada) y creó el archivo resultante .txt. En segundo lugar, debido a que .txt comienza
por un ., es un "archivo oculto", así como ls -a lo revela.
[prince@station prince]$ ls -a
.
.bash_profile
.gtkrc
..
.bashrc
.kde
.bash_history .gnome-desktop ode_to_apple.txt
.bash_logout
.gnupg
.pgpkey
[prince@station prince]$ cat .txt
Oh, I like them squishy

.plan
.txt
.viminfo
.xauthizv2EF

El usuario prince puede salir de esta situación utilizando corchetes para delimitar el
nombre deseado de la variable.
[prince@station prince]$ echo "Oh, I like them squishy" > ${A}_ode.txt
[prince@station prince]$ ls
apple_ode.txt ode_to_apple.txt

Utilizar corchetes para delinear nombres de variable siempre es correcto y en algunos
casos, es necesario.
Al terminar con una variable, la variable se puede desligar de su valor con el comando
unset.
[prince@station prince]$ unset A
[prince@station prince]$ echo $A
[prince@station prince]$

Variables de Bash
El siguiente cuadro lista algunas variables que se establecen automáticamente con la
shell bash. Estas variables son de sólo lectura y no pueden ser configuradas por el
usuario.
20

La shell bash
Table 1. Variables Bash de sólo lectura
Variable

Se expande hasta

?

El estatus de salida del comando ejecutado más recientemente

-

Opciones de banderas de la shell actualmente activadas

$

Id (pid) del proceso de la shell actual

!

Id (pid) del proceso del comando secundario más reciente

_

Último símbolo del comando anterior

PPID

Id (pid) del proceso padre de la shell.

SHELLOPTS

Lista separada por comas de las opciones de shell actual como lo informó
el comando set -o.

UID

El userid del usuario actual

Estas variables son establecidas por la shell para proveer información. Estas no se
pueden reasignar por el usuario, así como prince lo descubre a continuación.
[prince@station prince]$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactivecomments:monitor
[prince@station prince]$ SHELLOPTS=foo
-bash: SHELLOPTS: readonly variable

Las siguientes variables son inicializadas por la shell bash, pero pueden ser reasignadas.
Table 2. Variables Bash preasignadas
Variable

Se expande hasta

BASH_VERSION La versión actual bash
HOSTNAME

El nombre del host DNS de la máquina actual

OLDPWD

El directorio de trabajo anterior

PWD

The current working directory

RANDOM

Un número aleatorio entre 0 y 32767

SECONDS

El número de segundos desde que la shell se inició

Variables de entorno
El configurar y resolver variables debería ser bastante sencillo, (siempre y cuando se
acuerde de los espacios). Ahora presentaremos un concepto un poco más sutil y mucho
más útil: variables de entorno.
Así como la shell bash permite asignar parejas de valores-nombre llamados variables de
shell, el kernel de Linux permite a cualquier proceso definir las parejas nombre-valor
21

La shell bash
llamadas variables de entorno. Estas variables son una parte del proceso almacenado en
el kernel, simplemente como el id del proceso, el id del usuario y el directorio actual de
trabajo son parte del proceso. Lo más importante es que cada vez que se inicie un
proceso (tal como la shell bash iniciando el comando ls), las variables de entorno son
heredadas por el proceso hijo. Esto le permite a los usuarios utilizar la shell bash para
crear o modificar una variable de entorno y luego todos los comandos iniciados por la
shell heredarán esa variable.
¿Cómo creamos variables de entorno dentro de la shell bash? Primero, una variable de
shell se crea y luego la variable de shell es "promovida" a una variable de entorno
mediante el comando export, (la variable será luego exportada a cualquier proceso hijo
futuro). Considere el siguiente ejemplo:
[prince@station prince]$ A=apple
[prince@station prince]$ B=banana
[prince@station prince]$ echo a:$A b:$B
a:apple b:banana
[prince@station prince]$ export A
[prince@station prince]$ bash
[prince@station prince]$ ps
PID TTY
TIME CMD
2251 pts/5
00:00:00 bash
2316 pts/5
00:00:00 bash
2342 pts/5
00:00:00 ps
[prince@station prince]$ echo a:$A b:$B
a:apple b:
[prince@station prince]$ exit
exit
[prince@station prince]$ echo a:$A b:$B
a:apple b:banana
[prince@station prince]$ unset A B

El usuario prince ha creado dos variables de shell, A y B.
La variable A se promueve a una variable de entorno con el comando export.
El usuario prince inicia una subshell bash.
Al ejecutar el comando ps, prince confirma que hay otras shells ejecutándose: el
padre y el hijo (su shell actual).
Dado que la variable A pasa a ser una variable de entorno, ésta fue heredada por la
shell hija del padre. Por el contrario, la shell hija no sabe nada de la variable de
shell padreB.
Cuando prince sale de la shell hija, vuelve a la shell padre, donde la variable B está
aún definida.
Por último, prince desenlaza tanto la variable de entornoA como la shell de entorno
B con el mismo comando unset.
Las variables de entorno suelen utilizarse para configurar comandos con información
acerca de configuraciones locales o en otras palabras, la información acerca del entorno
local. A manera de ejemplo, muchos comandos buscarán una variable de entorno
22

La shell bash
llamada LANG para determinar el lenguaje del usuario y modificar su salida como
corresponde.
[prince@station prince]$ echo $LANG
en_US.UTF-8
[prince@station prince]$ date
Fri Aug 1 11:54:24 EDT 2002
[prince@station prince]$ LANG=de_DE
[prince@station prince]$ date
Fre Aug 1 11:54:53 EDT 2002
[prince@station prince]$ LANG=es_ES
[prince@station prince]$ date
vie ago 1 11:55:09 EDT 2002

Al establecer la variable de entorno LANG para de_DE, la abreviatura habitual para el día
"viernes" en alemán entonces se convierte en la abreviación alemana por regla. Al
establecer LANG como es_ES, los efectos son incluso más obvios, puesto que las
abreviaturas de los días y meses han cambiado al español (como también las
convenciones de las mayúsculas).
Un punto importante que merece reformularse. El comando date no cambió la conducta
porque el comando bash tenía una variable de entorno denominada LANG
(directamente). El proceso al ejecutar el comando date modificó su salida porque tenía
su propia variable de entorno llamada LANG. Esto simplemente sucedió para heredar esta
variable de la shell bash. Todos los procesos tienen variables de entorno, no sólo shells.
¿Por qué prince no tuvo que exportar explícitamente la variable LANG? La variable ya es
una variable de entorno configurada por los scripts de arranque. Una vez que una
variable es una variable de entorno, se puede modificar ( y suprimir) mediante la misma
sintaxis de las variables de shell.
A menudo, los usuarios utilizan una sintaxis más corta para crear y exportar una
variable de entorno:
[prince@station prince]$ export EDITOR=nano

Con este sólo comando, prince ha creado, asignado y exportado la variable EDITOR.
Listado de variables
Examinar variables con set y env
La shell bash provee dos comandos para listar variables definidas. El comando set, sin
argumentos, lista las variables de shell y las variables de entorno asociadas con la shell,
mientras que el comando env, otra vez sin argumentos, lista sólo variables que han sido
exportadas al entorno.
[prince@station prince]$ set
BASH=/bin/bash
23

La shell bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release"
[5]="i386-redhatlinux-gnu")
BASH_VERSION='2.05b.0(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=80
...
[prince@station prince]$ env
HOSTNAME=localhost
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
USER=prince
MAIL=/var/spool/mail/prince
...

Variables de entorno más utilizadas
El siguiente cuadro lista algunas variables de entorno que con frecuencia se utilizan para
personalizar un entorno de usuario.
Table 1. Variables de entorno más utilizadas
Variable
TERM

Uso
Especifica la configuración de bajo nivel de la terminal del usuario. La
variable es más relevante al utilizar una consola de línea serial ("terminal
tonta") para acceder al sistema.

PATH

Especifica los directorios para buscar archivos ejecutables en ellos.

DISPLAY

Especifica qué clientes del servidor X deberían usar el entorno gráfico.

LANG

Especifica el lenguaje preferido para los programas internacionalizados.

EDITOR

Muchos programas dependen de un editor externo para la entrada de parte del
usuario. A menudo, el editor por defecto es vi. Si la variable de entorno
EDITOR está establecida, el editor especificado se utilizará en su lugar.

PRINTER

La mayoría de los comandos que envían o administran trabajos de impresión
examinarán esta variable de entorno para determinar la impresora
predeterminada.

Ejemplos
Uso de variables para hacer referencia a las palabras más utilizadas
El usuario prince desea mantener al día los aspectos relacionandos con el software de
Open Source y suele utilizar los enlaces de texto del navegador web links para visitar
http://www.redhat.com/opensourcenow/key_issues.html. En lugar de teclear de modo
repetitivo la URL, prince modifica su archivo ~/.bashrc, para que la URL sea
almacenada en la variable OSNISSUES. Ahora prince puede referirse a la página web de
un modo más fácil.
24

La shell bash
[prince@station prince]$ vim .bashrc
[prince@station prince]$ cat .bashrc
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
OSNISSUES=http://www.redhat.com/opensourcenow/key_issues.html
[prince@station prince]$ bash
[prince@station prince]$ links $OSNISSUES

Mediante http_proxy para definir un servidor Proxy HTTP
Dado que prince está utilizando un computador sin conexión directa al internet, debe
configurar su navegador de red para usar el servidor proxy encontrado en la dirección IP
10.1.1.1 y en el puerto 8080. Mientras trata de entender cómo establecer un servidor
proxy para el navegador de texto links, se encuentra con lo siguiente en la página de
manual links(1).
PROTOCOL_proxy
that can act

Links supports the use of proxy servers
as firewall gateways and caching servers.

They are
preferable
servers

to

the

older

gateway

(see
WWW_access_GATEWAY,

below).

Each protocol

used by
Links, (http, ftp, gopher, etc), can be
mapped separately by setting environment variables of
the form
PROTOCOL_proxy (literally:

HTTP_proxy,

FTP_proxy,
HTTPS_proxy, etc), to
"http://some.server.dom:port/".

Con el fin de establecer el servidor proxy, agrega la siguiente línea a su archivo
~/.bashrc.
HTTP_proxy=http://10.1.1.1:80

Prince inicia una nueva shell (para que el archivo .bashrc sea leído) y trata de tener
acceso a la página web de Open Source.
[prince@station prince]$ links
http://www.redhat.com/opensourcenow/key_issues.html
Looking up www.redhat.com
www.redhat.com
Unable to locate remote host www.redhat.com
Alert!: Unable to connect to remote host.
25

La shell bash
links: Can't access startfile
http://www.redhat.com/opensourcenow/key_issues.html

El navegador de enlaces aparentemente no está tratando de usar el servidor proxy.
Cuando prince revisa sus pasos, se da cuenta que aunque configuró la variable
http_proxy, olvidó exportar la variable. Dado que la variable es una variable de shell
establecida y no una variable de entorno, no es heredada por el proceso links. Prince
edita la línea que agregó a su archivo .bashrc, agregándole la palabra exportar:
[prince@station prince]$ cat .bashrc
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
export HTTP_proxy=http://10.1.1.1:80

De nuevo inicia una nueva shell (para que lea el archivo .bashrc otra vez) y ensaya una
vez más.
[prince@station prince]$ links
http://www.redhat.com/opensourcenow/key_issues.html

Dado que la variable http_proxy ahora es exportada como una variable de entorno, es
heredada por el proceso links, y links usa con éxito el servidor de proxy para contactar
el sitio. Puesto que prince incluyó la línea en su archivo ~/.bashrc, la variable de
entorno se configurará automáticamente cada vez que inicie una nueva shell, y prince no
necesita preocuparse por esto.
Agregar un directorio a su PATH
Cuando la shell bash examina una línea de comandos, asume que la primera palabra es
el nombre del programa que se va a ejecutar. Luego debe ubicar el archivo que contiene
el programa en el sistema de archivos. Dado que la búsqueda de un archivo ejecutable,
por ejemplo, ls en todo un sistema de archivos, tardaría mucho, la shell busca en la
variable de entorno PATH para obtener instrucciones.
La variable de entorno PATH contiene una lista de directorios en los cuales deberían
buscar los archivos ejecutables, separados por una coma:
[prince@station prince]$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/home/prince/
bin
26

La shell bash
Considere ejecutar el comando xclock, el cual comienza por un reloj en el entorno
gráfico X. Por medio de la variable PATH, bash primero busca el archivo /bin/xclock,
y al no encontrarlo, busca entonces /usr/bin/xclock. El proceso continua hasta
encontrar el archivo ejecutable /usr/bin/X11/xclock.
No todos los archivos ejecutables en el sistema residen en directorios que están en la
lista por su variable de entorno PATH. Se dice que algunos programas viven "fuera de su
ruta". Sin embargo, el hecho que un programa viva fuera de su ruta, no significa que no
pueda ejecutarse. Significa que usted debe especificar el comando mediante una
referencia absoluta.
A manera de ejemplo, el comando lsof lista los archivos actualmente abiertos en el
sistema, (el nombre se deriva del inglés LiSt Open Files.) Dado que este comando lo
suelen utilizar administradores de sistemas, y no usuarios "normales", el comando vive
en el directorio /usr/sbin, el cual se adhiere "fuera del" PATH por defecto en Red Hat
Enterprise Linux. El usuario prince desearía usar el comando para listar todos los
archivos actualmente abiertos que el proceso init está utilizando.
[prince@station prince]$
-rwxr-xr-x
1 root
[prince@station prince]$
-bash: lsof: command not

ls -l /usr/sbin/lsof
root
95640 Jan 24
lsof -c init
found

2003 /usr/sbin/lsof

Al examinar su PATH, el directorio /usr/sbin no está listado, así que prince trata de
ejecutar el comando como una referencia absoluta.
[prince@station prince]$ /usr/sbin/lsof -c
COMMAND PID USER FD
TYPE DEVICE
SIZE
init
1 root mem
REG
3,3
27036
init
1 root mem
REG
3,3 104560
init
1 root mem
REG
3,3 1536292
2.3.2.so

init
NODE
245377
244833
476416

NAME
/sbin/init
/lib/ld-2.3.2.so
/lib/tls/libc-

Dado que él preferiría poder ejecutar el comando directamente, prince desearía agregar
el directorio /usr/sbin a su ruta. Utiliza un truco estándar de Linux (y Unix) para
agregar el directorio a su ruta.
[prince@station prince]$ PATH=$PATH:/usr/sbin

El comando puede ser pensado como si se dijera "establezca la variable PATH"sea
cualquiera que sea actualmente, pero luego agregue :/usr/sbin. Tras examinarlo, la
variable PATH ha agregado el directorio /usr/sbin y prince ahora puede listar los
archivos fácilmente.
[prince@station prince]$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/home/prince/
bin:/usr/sbin
[prince@station prince]$ lsof -c init
COMMAND PID USER FD
TYPE DEVICE
SIZE
NODE NAME
init
1 root mem
REG
3,3
27036 245377 /sbin/init
27

La shell bash
init
init
2.3.2.so

1 root mem
1 root mem

REG
REG

3,3 104560 244833 /lib/ld-2.3.2.so
3,3 1536292 476416 /lib/tls/libc-

Ejercicios en línea
Lab Exercise
Objetivo: Establecer y apuntar correctamente varias variables de shell y de
entorno.
Estimated Time: 30 mins.
Especificaciones
Estas especificaciones deben aplicarse a las shells recién iniciadas. Edite el script de
arranque de bash .bashrc (que se encuentra al comienzo de su directorio de inicio)
para incluir los comandos apropiados.
1. Su shell debe incluir el directorio /usr/sbin en su ruta de búsqueda de archivos
ejecutables.
2. Tras el arranque, su shell debería crear la variable de entorno PRINTER que
apunte a la palabra sales.
3. Sólo por gusto, tras el arranque, haga que su shell establezca la variable
HISTSIZE en su proceso actual de shell, (¿qué efecto tendrá esto en su historial
de comandos de shell?)
4. Tras el arranque, su shell debería crear la variable de shellCLICHE, la cual
debería apuntar a la frase en inglés that is how the cookie crumbles. Asegúrese
que la variable no se convierta en una variable de entorno.
5. Tras el arranque, su shell debe redirigir la salida del comando date al archivo en
su directorio de inicio titulado ppid_is_my_parent, en donde ppid es
remplazado por su id del proceso padre de shell (almacenado en la variable de
shell PPID).
Si ha configurado su archivo de shell .bashrc correctamente, debería poder reproducir
una salida similar a la siguiente.
[student@station student]$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/sbin:/ho
me/student/bin
[student@station student]$ echo $PRINTER
sales
[student@station student]$ ps
PID TTY
TIME CMD
3914 pts/3
00:00:00 bash
3948 pts/3
00:00:00 ps
[student@station student]$ echo $HISTSIZE
3914
[student@station student]$ echo $CLICHE
that is how the cookie crumbles
28

La shell bash
[student@station student]$ echo $PPID
4293
[student@station student]$ ls
4293_is_my_parent

Deliverables
A title
Question 1

Un archivo de arranque bash.bashrc configurado correctamente, para que las shells
recién creadas bash tengan la siguiente configuración.
1. El directorio /usr/sbin está incluído en la ruta de búsqueda de la shell.
2. La variable de entorno PRINTER apunta a sales.
3. La variable de entorno HISTSIZE apunta al id (PID) del proceso actual de la
shell.
4. La variable de shell CLICHE (no es una variable de entorno) apunta a la frase en
inglés that is how the cookie crumbles.
5. Tras el arranque, la salida del comando date es redirigida al archivo titulado
ppid_is_my_parent en su directorio de inicio, donde ppid es remplazado por
el id del proceso padre de la shell.

Limpieza
Después de que su ejercicio haya sido calificado, probablemente querrá suprimir los
cambios hechos en el archivo .bashrc, (en caso contrario, podría terminar con un
amplio historial, y demasiados archivos molestos soso_is_my_parent.)
Capítulo 4 Expansión de la línea de comandos
Conceptos clave
•
•
•
•
•

La shell bash expande ciertos metacaracteres de línea de comandos antes de
interpretar el comando.
La expansión con la tilde amplía los símbolos que comienzan por una tilde (~) a
los directorios de inicio de usuarios.
La expansión de llaves amplía los símbolos con corchetes ({}) en palabras
múltiples, cada una contiene una sola palabra a partir de la lista especificada.
La sustitución de comandos expande el texto delimitado por comillas invertidas
(``) o "dólar paréntesis" ($()) en la salida producida por el comando encerrado.
Las comillas dobles ("..." ), las comillas sencillas ('...') y el caracter de barra
invertida pueden usarse para evitar que la shell expanda los caracteres.
29

La shell bash
Expansiones de línea de comandos
Generalidades
Antes de ejecutar un comando, la shell bash ejecuta varias expansiones en la línea de
comandos. Varios tipos de expansiones de bash, tales como la expansón del nombre de
ruta (comodín) y la expansión de variables ya se han descrito. El siguiente cuadro lista
los tipos de expansiones bash con una descripción de cada una a continuación.
Table 1. Expansiones de línea de comandos en la shell bash
Expansión
Historial

Sintaxis
!

Se expande hasta
Una línea de comandos anterior

Llaves

{}

Texto especificado

Tilde

~username

Directorio de inicio de un usuario

Variable

$, ${...}

Shell y variables de entorno

Aritmética

$((...))

Cálculo numérico

Sustitución de
comandos

`...`, $(...)

Salida de la ejecución del comando en una
subshell

Nombre de ruta

*, ?, [...],
[^...]

Nombres de archivos coincidentes en el sistema
de archivos

Expansión del historial
La expansión del historial, la cual se invoca con un signo de exclamación, se describió
de modo extensivo en una lección anterior. Aquí se incluye debido al contexto.
Expansión de llaves
La expansión de llaves expande una sola palabra en palabras múltiples, sustituyendo
uno de los elementos en "llave" para cada palabra. Por ejemplo, la expresión {c,b,r}at
se expandiría en tres palabrascat bat rat. La expansión de llaves se utiliza para
referirse (o crear) archivos que tienen prefijos, postfijos o componentes de ruta
comunes, (recuerde que varios ejercicios de laboratorio han utilizado expansión de
llaves para crear rápidamente un gran número de directorios o archivos y luego
subdirectorios dentro de ellos).
[prince@station prince]$ mkdir chap{01,02,03,04}

El usuario prince ahora tiene los siguientes cuatro directorios:
.
|-- chap01/
|-- chap02/
|-- chap03/
30

La shell bash
`-- chap04/
4 directories, 0 files

[prince@station prince]$ mkdir chap{01,02,03,04}/{html,text}

Ahora se han agregado los siguientes directorios.
.
|-|
|
|-|
|
|-|
|
`--

chap01/
|-- html/
`-- text/
chap02/
|-- html/
`-- text/
chap03/
|-- html/
`-- text/
chap04/
|-- html/
`-- text/

12 directories, 0 files

En el primer comando mkdir, la palabra entre corchetes se expande a cuatro directorios
chap01, chap02, chap03, y chap04. En el segundo comando mkdir, la palabra con
doble corchete se expande a ocho directorios chap01/html, chap01/text,
chap02/html y así sucesivamente.
A diferencia de los archivos/comodines, las palabras que resultan de la expansión de
llaves no coinciden con los archivos en el sistema de archivos (los archivos no tienen
que existir). De hecho, las palabras expandidas no tienen que ser nombres de archivos,
aunque en la práctica suelen serlos.
Expansión de tilde
Quizás este es el concepto más sencillo de expansión, la expansión de tilde, el cual
expande un ~nombredeusuario para el usuario del directorio de inicio del
nombredeusuario, como se listó en el archivo/etc/passwd (o la base de datos
apropiada del usuario). A continuación, prince utiliza la expansión tilde para referirse a
su directorio propio y a los directorios de elvis, y luego un subdirectorio del directorio
de inicio de elvis.
[prince@station
drwx-----x
15
drwx-----x
9
[prince@station
total 4
drwxrwxr-x
2

prince]$
elvis
prince
prince]$

ls -ld ~ ~elvis
elvis
4096 Jul 21 17:41 /home/elvis
prince
4096 Aug 4 06:58 /home/prince
ls -l ~elvis/pub

elvis

music

4096 Jul 13 05:46 music
31

La shell bash
A menudo en este curso y en otros textos, la tilde se utiliza para implicar que un archivo
debería existir en el directorio de inicio del usuario, tal como el archivo
~/.bash_history. Ahora podemos ver la razón de esta convención.
Expansión de variables
La expansión de variables se trató de modo extenso en la lección anterior.
Reformulando, la shell bash expandirá (desreferenciará) expresiones de la forma
$VARNAME o ${VARNAME} al valor de la shell o variable de entornoVARNAME.
Expansión aritmética
La shell bash suele considerarse un entorno deficiente para cálculos numéricos y los
operadores aritméticos tales como +, -, *, y / en la línea de comando no tienen el
significado matemático habitual. Sin embargo, la shell bash trata de manera especial
texto delimitado con una sintaxis $((...)). Primero, las variables se tratan como enteros
numéricos cuando resulte apropiado, y segundo, los operadores matemáticos estándar
como por ejemplo +, -, *, y / se tratan como tal. La shell bash "expandirá" toda la
expresión y la remplazará por el resultado numérico. Los operadores aritméticos son los
mismos del lenguaje de programación C y están totalmente documentados en la página
de manual bash(1) bajo "EVALUACIÓN ARITMÉTICA".
En el siguiente ejemplo, prince utilizará una expansión aritmética para calcular el área
de un rectángulo.
[prince@station prince]$ WIDTH=16
[prince@station prince]$ HEIGHT=82
[prince@station prince]$ echo $(( $WIDTH * $HEIGHT))
1312

Sin embargo, las limitaciones de cálculos numéricos se descubren rápidamente cuando
prince trata de volver a calcular el área mediante un número de punto flotante.
[prince@station prince]$ WIDTH=16.8
[prince@station prince]$ echo $(( $WIDTH * $HEIGHT))
-bash: 16.8 * 82: syntax error in expression (error token is ".8 *
82")

La shell bash sólo soporta enteros aritméticos.
Sustitución de comandos
Quizás de las expansiones más complejas y útiles, la sustitución de comandos permite a
los usuarios ejecutar comandos arbitrarios en la subshell e incorporar los resultados
dentro de la línea de comandos. La sintaxis de la"vieja escuela" para la sustitución de
comandos es encerrar el comando entre "acentos graves" (la comilla simple inclinada
hacia la izquierda que se encuentra en la misma tecla de ~, cerca de 1 en la mayoría de
los teclados), y el comando de sustitución suele denominarse "sustitución de acentos
32

La shell bash
graves". La sintaxis más moderna soportada por la shell bash es similar a la expansión
aritmética, pero con solo un par de paréntesis: $(subcomando)
Como ejemplo de una sustitución de comandos, prince desearía crear un directorio que
contenga la fecha en su nombre. Después de examinar la página de manual date(1), crea
una cadena de formato para generar la fecha en un formato compacto.
[prince@station prince]$ date +%d%b%Y
04May2003

Ahora, ejecuta el comando mkdir mediante la sustitución de comandos.
[prince@station prince]$ mkdir reports.$(date +%d%b%Y)
[prince@station prince]$ ls
reports.04May2003

O pudo haber combinado las ventajas de la sustitución de comandos y la sustitución del
historial como se muestra a continuación.
[prince@station prince]$ mkdir reports.$(!da)
mkdir reports.$(date +%d%b%Y)
[prince@station prince]$ ls
reports.04May2003

La shell bash implementa la sustitución de comandos al generar una nueva subshell,
ejecutar el comando, registrar la salida y salir de la subshell. El texto se utiliza para
invocar la sustitución de comandos luego es remplazado por la salida registrada desde el
comando.
Expansión de nombre de ruta
La expansión de nombre de ruta o "comodín de archivo", se describió en el cuaderno
anterior, pero no se introdujo como una expansión de shell. Ahora podemos ver que el
nombre de ruta es uno de los tipos de expansiones implementados por la shell bash.
Para repasar, la sintaxis de la expansión del nombre de ruta vea la siguiente tabla.
Table 1. Expansión del nombre de ruta bash
Caracter

Coinciden

*

0 ó más caracteres

?

exactamente un caracter

[...]

exactamente uno de los caracteres incluídos

[^...]

exactamente uno de los caracteres excluídos

Comillas y caracteres de escape
33

La shell bash
La shell bash usa varios caracteres de puntuación que se encuentran en el teclado para
ejecutar diferentes tipos de expansiones, redirecciones y otra clase de actos de expertos.
Aunque es eficaz, hay situaciones en que los usuarios desean utilizar uno de estos
caracteres sin la invocación de ningún tipo de conducta especial. Parafraseando a
Sigmund Freud, "A veces un signo dólar es sólamente un signo de dolar."
La shell bash proporciona tres mecanismos para evitar que los caracteres sean
interpretados por la shell, escapando, utilizando comillas dobles o sencillas.
Table 1. Uso de comillas y escape de la shell bash
Efecto

Sintaxis


Impide que el siguiente caracter sea interpretado por la shell.

"..."

Impide que los caracteres incluídos sean interpretados por la shell,
exceptuando los caracteres $, !, y ` (acento grave).

'...'

Impide que todos los caracteres incluídos sean interpretados por la shell.

Considere los siguientes ejemplos, donde prince está tratando de imprimir en pantalla.
En el primer caso, prince define la variable CAR, y trata de imprimir la línea sin
comillas.
[prince@station prince]$ CAR=corvette
[prince@station prince]$ echo <pre>little red $CAR</pre>
-bash: syntax error near unexpected token `newline'

Sin comillas, bash interpretó los caracteres > y < como solicitudes para redirigir la
salida (y entrada) del comando. La shell se confundió cuando se le pidió redirigir la
salida dos veces. El usuario prince, trata de nuevo, esta vez utilizando comillas dobles.
[prince@station prince]$ echo "<pre>little red $CAR</pre>"
<pre>little red corvette</pre>

En este caso, las comillas dobles protegieron los caracteres < y >. Sin embargo, el signo
de dólar, todavía se interpreta como marcador para una variable. El usuario prince
intenta de nuevo con comillas sencillas.
[prince@station prince]$ echo '<pre>little red $CAR</pre>'
<pre>little red $CAR</pre>

En este caso, todos los caracteres de puntuación fueron protegidos de la interpretación
de la shell. Como una alternativa, los caracteres pueden escaparse individualmente con
una barra invertida precedente.
[prince@station
<pre>little red
[prince@station
>pre<little red

prince]$ echo <pre>little red $CAR</pre>
corvette</pre>
prince]$ echo <pre>little red $CAR</pre>
$CAR</pre>
34

La shell bash
Una nota sobre las comillas
Como hemos visto, bash hace uso de una variedad de signos de puntuación
relacionados con comillas, asignando a cada uno un propósito diferente. Los tres estilos
de comillas se ilustran con el comando echo de abajo. Con el fin de reforzar las
diferencias, los tres estilos de comillas se describen a continuación.
[prince@station prince]$ FOOD=guacamole
[prince@station prince]$ echo "wow! `whoami` sells $FOOD" 'for $!'
wow! prince sells guacamole for $!

Comillas dobles: "..."
Las comillas dobles se utilizan en situaciones donde usted desearía tratar la
mayoría de la puntuación literalmente o combinar palabras en un sólo símbolo,
pero aún puede hacer uso de variables, sustitución de comandos y sustitución de
historial.
Comillas sencillas inclinadas a la derecha (apóstrofes): '...'
Las comillas sencillas son las más poderosas y se utilizan en situaciones
similares a las comillas dobles cuando quiere que toda la puntuación, incluyendo
las variables y la sustitución de comandos, se traten literalmente.
Comillas sencillas inclinadas hacia la izquierda (acentos graves): `...`
Los acentos graves son básicamente diferentes a las comillas simples o dobles,
no son para citar. Estos acentos se utilizan para invocar la sustitución de
comandos en el texto incluido.
Sutilezas de la expansión de línea de comandos
Hemos visto que bash se aplica a un gran número de expansiones de línea de comandos
antes de que un comando se ejecute. La frase incluye una sutileza que no siempre es
apreciada y puede algunas veces llevar a confusiones. Las expansiones de shell se
presentan antes de que el comando se ejecute. A veces, algunos los comandos esperan
argumentos que contienen caracteres especiales para la shell bash. Un ejemplo es el
comando find. Si no se tiene cuidado al utilizar comillas o escapar los caracteres
especiales, bash podría "expandirlos" antes de que el comando los vea. El siguiente
ejemplo del comando find en acción podría ayudar.
Al iniciar desde un directorio vacío, prince ejecuta find para buscar todos los archivos
terminados en .conf en el directorio /etc.
[prince@station prince]$ find /etc -name *.conf
find: /etc/sysconfig/pgsql: Permission denied
/etc/sysconfig/networking/profiles/default/resolv.conf
/etc/sysconfig/networking/profiles/netup/resolv.conf
find: /etc/default: Permission denied
/etc/X11/gdm/factory-gdm.conf
35

La shell bash
/etc/X11/gdm/gdm.conf
/etc/modprobe.conf
...

Pasando por alto algunas quejas acerca de los directorios inaccesibles, el comando
funciona. Luego, prince crea los archivos a.conf y b.conf en el directorio local e
intenta de nuevo.
[prince@station prince]$ touch a.conf b.conf
[prince@station prince]$ ls
a.conf b.conf
[prince@station prince]$ find /etc -name *.conf
find: paths must precede expression
Usage: find [path...] [expression]

¿Por qué el comando que funcionó hace apenas unos segundos no funciona ahora? La
respuesta, como podría esperarse, tiene que ver con la expansión de línea de comandos.
Primero, veamos el segundo caso. La shell bash encontró el siguiente comando.
find /etc -name *.conf

¿Qué hace primero bash? Aplica la expansión de línea de comandos. Después de
examinar el directorio local y hallar los archivos a.conf y b.conf, la shell remplaza el
comodín *.conf con los nombres de archivo coincidentes, a.conf b.conf. Esta es una
expansión de nombre de ruta bastante antigua. Después de la expansión, el comando se
ve de esta manera.
find /etc -name a.conf b.conf

Ahora bash ejecuta el comando, el cual genera un mensaje de error (porque la opción name no pudo manejar dos argumentos).
Volviendo al primer comando, ¿por qué funcionó? Al implementar la expansión del
nombre de ruta, la shell bash intenta ayudar a la gente. Si un comodín "falta " (por
ejemplo, ningún archivo coincide con la expresión especificada), bash conserva el
comodín. En el primer caso, como ninguno de los archivos coincidió con *.conf, bash
pasó el argumento al comando find como está escrito. [1]
¿Cuál es la forma correcta de manejar la situación? Usar comillas o escapar los
caracteres especiales, como se muestra a continuación:
[prince@station prince]$ find /etc -name "*.conf"
find: /etc/sysconfig/pgsql: Permission denied
find: /etc/default: Permission denied
/etc/sysconfig/networking/profiles/default/resolv.conf
/etc/sysconfig/networking/profiles/netup/resolv.conf
/etc/X11/gdm/factory-gdm.conf
/etc/X11/gdm/gdm.conf
/etc/modprobe.conf
...
36

La shell bash
Debido a que se ha utilizado el * , la shell bash no intentará realizar una expansión de
nombre de ruta y el comando funciona como se desea. La lección es: si está pasando un
caracter especial dentro de un comando, usted debería proteger el caracter con comillas
(o un escape de barra invertida).
Ejemplos
Uso de expansión de llaves
El usuario prince está configurando un directorio llamadoogg en el que va a almacenar
archivos de música que ha "quemado" (copiado) de sus discos favoritos. Con el fin de
organizar las cosas, le gustaría crear directorios basados en estilos diferentes de música
y en cada uno de los subdirectorios crear un archivo llamado playlist. En la siguiente
transcripción, prince usa una expansión de llave para agilizar su trabajo.
[prince@station prince]$ mkdir ogg
[prince@station prince]$ mkdir ogg/{blues,folk,rap,pop}
[prince@station prince]$ touch ogg/{blues,folk,rap,pop}/playlist

En este punto, prince ha creado la siguiente estructura de directorio.
ogg/
|-- blues
|
`-- playlist
|-- folk
|
`-- playlist
|-- pop
|
`-- playlist
`-- rap
`-- playlist
4 directories, 4 files

¿Pudo prince haber utilizado el comodín de archivo (expansión de nombre de ruta) en su
lugar? Al utilizar el comando mkdir, el comodín de archivo habría sido inútil porque
los directorios blues, folk, etc.., no existían. ¿Qué sucedería si prince hubiera utilizado
el comodín de archivo para el comando touch?
[prince@station prince]$ touch ogg/*/playlist
touch: creating `ogg/*/playlist': No such file or directory

Los directorios blues, folk, etc., existeron, pero ninguno de los archivos playlist
existia, por lo tanto el comodiín se perdió. Para situaciones en que el archivo podría o
no existir, la expansión de llaves tiende a funcionar mejor que el comodín.
Más acerca de la terminación con el tabulador
Hemos visto que la shell bash graba las pulsaciones al completar nombres de comandos
o nombres de archivos cuando se pulsa la tecla TAB. La shell bash completará nombres
de usuario y variables, cuando las palabras comienzan por los caracteres ~ o $,
37

La shell bash
respectivamente. Por ejemplo, si un usuario escribe ~el<TAB>, bash podría completar el
símbolo ~elvis. De la misma manera, $PA<TAB> podría completarse $PATH. De forma
similar a la expansión del comando y nombre de archivo, si los caracteres iniciales
tecleados hasta el momento no especifican únicamente una variable (o nombre de
usuario), bash emite un pitido. Al pulsar dos veces el TAB se listarán las posibles
terminaciones.
Poner entre comillas los nombres de archivos raros
En un cuaderno anterior, mencionamos que los nombres de archivo en Linux (y Unix)
podrían estar compuestos por cualquier caracter a excepción de uno (¿Recuerda cuál?[1])
En el mismo cuaderno, se les dijo a los estudiantes que aunque se podían utilizar
caracteres especiales, era mejor evitarlos. Ahora estamos en una buena posición para ver
el porqué. Suponga que prince quiere crear un archivo único llamado Make $$$ *Fast*
!!.
[prince@station prince]$ touch Make $$$ *Fast* !!
touch Make $$$ *Fast* l
[prince@station prince]$ ls
13986$ *Fast* l Make

El comando touch accede, creando los archivos que bash le pide hacer. Primero, como
los símbolos están separados por espacios, bash los trata como cuatro palabras
separadas. Luego la shell bash aplica sus distintas expansiones a las palabras.
1. El archivo Make se crea fácilmente.
2. La shell bash aplica la sustitución de variables a $$$, resultando en 13986$.
(¿De dónde sale el número 13986?[2])
3. El símbolo *fast* sobrevive con el preservado del *, pero ese no tenía que ser
el caso.
4. Por último, !! se expande a l desde el historial de comandos del usuario, el cual
aparentemente (y un poco extraño) fue el anterior comando ejecutado.
Una vez se han aplicado las extensiones, la shell bash invoca touch con cuatro
argumentos, para que touch obedientemente cree cuatro archivos.
¿De qué manera persuadimos a bash para que cree un archivo con nuestro rito
proporcionado por Linux de incluir espacios y puntuación en el nombre de archivo?
Obviamente con comillas.
[prince@station prince]$ touch 'Make $$$ *Fast* !!'
[prince@station prince]$ ls
13986$ *Fast* l Make Make $$$ *Fast* !!

Con sólo ls, es difícil distinguir entre múltiples archivos y un archivo único con
espacios en el nombre. Un ls -l ayuda a aclarar la situación.
[prince@station prince]$ ls -l
total 0
38

La shell bash
-rw-rw-r--rw-rw-r--rw-rw-r--rw-rw-r--rw-rw-r-*Fast* !!

1
1
1
1
1

prince
prince
prince
prince
prince

prince
prince
prince
prince
prince

0
0
0
0
0

Aug
Aug
Aug
Aug
Aug

31
31
31
31
31

06:19
06:19
06:19
06:19
06:40

13986$
*Fast*
l
Make
Make $$$

Observe que las comillas sirven en realidad para dos propósitos.
1. Las comillas inhiben la interpretación de los signos de puntuación como lo
solicitan las expansiones de shell.
2. Las comillas impiden la división de palabras, la cual es la forma como la shell
bash compone argumentos para los programas que ejecuta. Por ejemplo, el
comando touch one two three haría que bash ejecute el comandotouch con
tres argumentos, one, two, y three. Por el contrario, el comando touch "one
two three" haría que bash pase el único argumento del comando touch a one
two three (aunque uno con espacios).
Ejercicios en línea
Lab Exercise
Objetivo: Usar varias sustituciones de shell bash de modo efectivo.
Tiempo estimado: 15 minutos.
Especificaciones
1. Configure su archivo ~/.bashrc para que, tras el arranque, la variable
LINUX_VERS contenga toda la primera línea del archivo /var/log/dmesg, (el
archivo /var/log/dmesg se regenera cada vez que se arranca la máquina, por lo
que deberá establecer la variable de modo dinámico. Recuerde que el comando
head -1 mostrará la primera línea del archivo).
2. En su directorio de inicio, cree archivos con los sigu¡entes nombres de archivo,
(el contenido de los archivos es irrelevante).
a. archivo sin título
b. **'s y ||'s
c. >> README!! <<
3. En su directorio de inicio, cree un subdirectorio denominado shirts. Dentro del
subdirectorio, cree 108 archivos de la forma estilo.tamaño.color.ext, donde
cada archivo contenga una combinación de valores a partir del cuadro siguiente.
Estilo

tee, crew, turtleneck

Tamaño

XXL, XL, L, M, S, XS

Color

red, yellow, blue

Extensión info, inv
39

La shell bash
4. Por ejemplo, el directorio debería contener archivos titulados
tee.XXL.red.info, tee.XXL.red.inv, tee.XL.red.info, tee.XL.red.inv y
así sucesivamente.
Deliverables
A title
Question 1

1. Tras el arranque, la variable LINUX_VERS debe establecerse para que contenga la
primera línea del archivo /var/log/dmesg.
2. Los archivos a continuación deberían existir en el directorio de inicio del
usuario.
a. archivo sin título
b. **'s y ||'s
c. >> README!! <<
3. Un directorio llamado ~/shirts, el cual contiene exactamente 108 archivos,
cada uno de forma estilo.tamaño.color.ext. Cada nombre de archivo
contiene una combinación de los valores que aparecen en el cuadro de arriba.

Capítulo 5 Personalización de la shell
Conceptos clave
•

•
•
•
•
•
•

La shell bash internamente implementa ciertos comandos sencillos que están
muy ligados con la conducta de la shell. Estos se conocen como los comandos
incorporados.
Los alias de shell crean comandos aparentes que expanden a texto arbitrario.
Los alias de shell se establecen y examinan con el comando alias.
Los alias de shell se remueven con el comando unalias.
El intérprete de comandos de la shell bash se puede personalizar mediante la
variable PS1.
Las banderas de shell se pueden establecer con el comando set -f y se limpian
con set +f.
Las opciones de shell se examinan, establecen y se anulan con el comando
shopt.

Esta lección se centra en las técnicas utilizadas para personalizar la shell bash, como
por ejemplo crear comandos alias, personalizar el intérprete de comandos de la shell y
establecer las opciones de la shell. La lección comienza con un tema que no es la
40

La shell bash
personalización real, pero está relacionada con la conducta de la shell, el tema de los
comandos internos.
Comandos internos de la shell
Al evaluar una línea de comandos, la shell trata la primera palabra como un comando.
La shell bash implementa algunos comandos de modo interno, lo que significa que los
comandos no existen en el sistema de archivos como un programa cargable, sino que la
shell misma los implementa. Estos comandos se conocen como comandos internos de la
shell. Estos suelen ser comandos sencillos relacionados con cambios a la shell misma.
En un cuaderno anterior, presentamos el comando which, el cual reportará en qué parte
del sistema de archivo reside el archivo ejecutable que contiene un comando en
particular. A continuación, madonna observa que el comando date es implementado por
el programa que se encuentra en el archivo ejecutable /bin/date:
[madonna@station madonna]$ which date
/bin/date

¿Qué sucede cuando madonna utiliza which para buscar el archivo ejecutable que
contiene el programa cd?
[madonna@station madonna]$ which cd
/usr/bin/which: no cd in
(/usr/local/j2sdk1.3.1/bin:/bin:/usr/bin:/usr/local/bin
:/usr/bin/X11:/usr/X11R6/bin:/home/madonna/bin)

De acuerdo con which, el comando cd no existe como ejecutable en el sistema de
archivos. El comando cd es un ejemplo de un comando interno de la shell. Una lista de
comandos internos de la shell y su documentación correspondiente se puede ver
mediante el comando help, el cual es en sí mismo un comando interno de la shell.
[madonna@station madonna]$ help
GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu)
These shell commands are defined internally. Type `help' to see this
list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this
list.
...
alias [-p] [name[=value] ... ]
bind [-lpvsPVS] [-m keymap] [-f fi
builtin [shell-builtin [arg ...]]
cd [-L|-P] [dir]
compgen [-abcdefgjksuv] [-o option
...

bg [job_spec]
break [n]
case WORD in [PATTERN [| PATTERN].
command [-pVv] command [arg ...]
complete [-abcdefgjksuv] [-pr] [-o
41

La shell bash
El comando help entrega una versión de la información sobre la shell, menciona un par
de sitios donde la documentación de bash puede encontrarse y presenta bota una lista de
comandos internos. Observe que la lista contiene el comando cd. El comando help
también se puede utilizar para ver documentación detallada acerca de un comando
interno específico.
[madonna@station madonna]$ help cd
cd: cd [-L|-P] [dir]
Change the current directory to DIR. The variable $HOME is the
default DIR. The variable CDPATH defines the search path for
the directory containing DIR. Alternative directory names in
CDPATH
are separated by a colon (:). A null directory name is the same
as
the current directory, i.e. `.'. If DIR begins with a slash (/),
then CDPATH is not used. If the directory is not found, and the
...

Dado que el comando cd está ligado a la conducta de la shell, es decir, cambia el
directorio de trabajo de la shell, este es un buen candidato para un comando interno.
Varios comandos que ya ha estado utilizando, tales como cd, pwd, y echo, son en
realidad internos de la shell.
Alias
Los alias permiten a los usuarios personalizar los nombres de los comandos o enlazar
comandos con las opciones o argumentos más utilizados. Una vez creados, los alias se
utilizan como si fueran cualquier otro comando.
El comando alias
Los alias se crean (y examinan) mediante el comando interno alias. Al crear alias, el
comando alias utiliza la siguiente sintaxis.
alias NAME=VALOR

Este comando crearía un alias denominado NOMBRE, el cual apuntaría al valor VALOR. La
sintaxis debería ser reminiscente a la utilizada para asignar variables de shell. En
particular, como en la asignación de variable, la asignación de alias no permite espacios
en ningún lado del signo de igual. Del mismo modo, dado que la sintaxis sólo espera un
símbolo único después del signo igual, las frases que contienen múltiples palabras
(separadas por espacios) deben ir entre comillas.
En el siguiente ejemplo, madonna establece el alias h como un atajo para el comando
head. Dado que el alias apunta a una sola palabra (head), madonna no tiene que
preocuparse por citar el valor. Luego utiliza el nuevo alias para examinar varias de las
primeras líneas del archivo /etc/services.
[madonna@station madonna]$ alias h=head
[madonna@station madonna]$ h /etc/services
42

La shell bash
# /etc/services:
# $Id: 010_text.dbk,v 1.3 2004/01/07 18:41:02 bowe Exp $
#
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single
well-known
# port number for both TCP and UDP; hence, most entries here have two
entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all
ports
# are included, only the more common ones.

En el siguiente ejemplo, madonna advierte que a menudo está listando todos los
procesos ejecutándose en la máquina con el comando ps aux. Decide entonces que cada
vez que ejecute ps, prefería la salida más completa que ps aux presenta y por lo tanto
establece un alias para el comando ps.
[madonna@station madonna]$ alias ps="ps aux"
[madonna@station madonna]$ ps
USER
PID %CPU %MEM
VSZ RSS TTY
STAT START
root
1 0.0 0.0 1376
72 ?
S
Aug30
root
2 0.0 0.0
0
0 ?
SW
Aug30
[keventd]
root
3 0.0 0.0
0
0 ?
SW
Aug30
root
4 0.0 0.0
0
0 ?
SWN Aug30
[ksoftirqd_CPU0]
root
9 0.0 0.0
0
0 ?
SW
Aug30
[bdflush]
root
5 0.0 0.0
0
0 ?
SW
Aug30
[kswapd]
...

TIME COMMAND
0:04 init [
0:00
0:00 [kapmd]
0:00
0:00
0:00

En este caso, puesto que ella quiso que el alias apuntara a una frase de dos palabras (ps
y aux), necesitó encerrar la frase entre comillas (para que tras "la división de palabras",
la shell trate la frase como una sola palabra).
El comando alias también se utiliza para examinar los alias actualmente definidos. Si
madonna quisiera repasar los alias que estableció podría sencillamente ejecutar el
comando alias (sin argumentos).
[madonna@station madonna]$ alias
alias h='head'
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias ps='ps aux'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot
--show-tilde'
43

La shell bash
El comando alias lista los alias establecidos por madonna (h y ps), como también otros
alias establecidos por los scripts de arranque bash de madonna (y son parte de la
configuración predeterminada de Red Hat Enterprise Linux).
Si se dan argumentos (sin el signo de igual), el comando alias mostrará el alias actual
para el argumento, si existe alguno:
[madonna@station madonna]$ alias ps h foo
alias ps='ps aux'
alias h='head'
-bash: alias: foo: not found

El comando unalias
Los alias se pueden suprimir con el comando interno de la shell unalias. Para suprimir
un alias, pase el nombre de alias como un argumento al comando unalias. A
continuación madonna suprime el alias que creó anteriormente para ps.
[madonna@station madonna]$ unalias ps
[madonna@station madonna]$ alias ps
-bash: alias: ps: not found

Evaluación de alias
¿Cuándo busca alias la shell de bash ? A diferencia de las variables, no hay signos de
puntuación asociados con ninguna clase de "expansión de alias". En su lugar, la shell de
bash busca alias en donde se espera un comando (es decir, como la primera palabra en
la línea de comando). Si la primera palabra es reconocida como un alias , el alias se
expande. La excepción es si el alias se expande al comando que tiene el mismo nombre
de alias en cuyo caso la shell simplemente ejecuta la expansión y sigue adelante, (de
otra manera, los usuarios podrían fácilmente crear alias que pondrían la shell en un
bucle infinito).
Los usuarios pueden no darse cuenta de que están usando alias en lugar del comando
mismo. Un buen ejemplo es la configuración predeterminada de Red Hat Enterprise
Linux, la cual alias el comando ls al valor ls --color=tty, (este instruye a ls para
proporcionar caracteres de control especiales que dan color a diferentes tipos de
archivos, pero solo si el comando está escribiendo en una terminal. Cuando se redirige a
un archivo, no se presenta ningún color).
Ejecución de comandos
Hemos descrito varios tipos de palabras considerados por la shell bash como
"comandos". Para resumir, y proveer un contexto, la siguiente lista resume los pasos que
la shell bash realiza al evaluar la primera palabra de la línea de comandos, (el siguiente
no es el algoritmo exacto, el cual es más complicado, pero sirve como una aproximación
útil).
44

La shell bash
1. Realiza cualquier expansión de la shell.
2. ¿La palabra se define como un alias? Si es así, expanda el alias y vuelva a
comenzar (a menos que el alias se expanda a un comando que tenga el mismo
nombre del alias en cuyo caso expande el alias y empieza de nuevo, pero no
vuelve a expandir alias).
3. ¿La palabra se define como una función de una shell? Si es así, llame la función
de la shell en la shell actual, (las funciones de la shell van más allá del alcance
de este curso, pero están incuídas aquí para completar la información).
4. ¿La palabra es un comando intermo de la shell? Si es así, ejecute el comando
interno.
5. ¿La palabra contiene un /? Si es así, ejecute el archivo si existe y tiene permisos
ejecutables.
6. Si la palabra no contiene un /, busque un archivo con un nombre similar en todos
los directorios en orden como se definió en el entorno de variable PATH. Si existe
un archivo coincidente y tiene permisos ejecutables, ejecute el archivo.
Personalizar el intérprete de comandos de bash
La shell bash interactiva, mientras que repite su bucle de "escuchar", "evaluar" y
"ejecutar", expide un intérprete de comandos cada vez que vuelve a la etapa de
"escuchar". El intérprete de comandos se utiliza para contarle al usuario que la
evaluación de la etapa anterior ha terminado y que la shell está esperando intrucciones.
En la configuración predeterminada de Red Hat Enterprise Linux , el intérprete de
comandos también provee más información, incluyendo el nombre de usuario actual,
nombre de la máquina y directorio de trabajo.
El comando bash en realidad tiene cuatro intérpretes de comandos diferentes los cuales
se utilizan en diferentes situaciones. Los dos más vistos son el intérprete de comandos
primario, utilizado cada vez que bash está listo para un nuevo comando y el intérprete
de comandos secundario utilizado cuando un usuario presiona la tecla INTRO, pero la
línea de comandos tiene obviamente una sintaxis inacabada (tal como unas comillas que
aún no se han cerrado). A continuación [madonna@station madonna]$ sirve de
intérprete de comandos primario, mientras que> sirve de intérprete de comandos
secundario.
[madonna@station madonna]$ echo "Little Miss Muffet
> Sat on a Tuffet"
Little Miss Muffet
Sat on a Tuffet

Personalización del intérprete de comandos de bash con PS1 y PS2
Los usuarios pueden personalizar los intérpretes de comandos de bash mediante las
variables de shell PS1 y PS2, las cuales bash usa para componer los dos prompts. El
ejemplo anterior implicó que el intérprete de comandos primario es la forma de decir de
bash "Estoy esperando", y el intérprete de comandos secundario es la forma de decir de
bash "Todavía estoy esperando". Para plantear el punto de una forma obvia, madonna
personalizará sus intérpretes de comandos para decir justo eso.
45

La shell bash
[madonna@station madonna]$ PS1="I'm waiting ... "
I'm waiting ... PS2="I'm still waiting ... "
I'm waiting ... echo "Hickory Dickory Dock
I'm still waiting ... three mice ran up the clock"
Hickory Dickory Dock
three mice ran up the clock
Estoy esperando ...

Inmediatamente tras cambiar el valor de la variable PS1, bash comenzó a utilizar el
nuevo valor como su intérprete de comandos primario.
A menudo los usuarios desearían que el intérprete de comandos también visualizara
información útil. La shell de bash permite a los usuarios insertar secuencias de escape
dentro de la definición de PS1, que remplaza con información dinámica cuando se
genera el intérprete de comandos. El cuadro a continuación resume algunas de las
secuencias más comunes. Para obtener una lista más completa, vea la página de manual
bash(1).
Table 1. Secuencias de escape comunes utilizadas en intérpretes de comandos bash
Secuencia

Expansión

a

Campana audible de la terminal

d

fecha en formato"día mes"

h

el nombre del host hasta el primer "."

T

La hora actual en formato de 12 horas HH:MM:SS

u

el nombre de usuario del usuario actual

W

el nombre de la base del directorio de trabajo actual

!

El número de historial de este comando

$

Si el UID efectivo es 0, un #, de lo contrario un $

nnn

el caracter correspondiente al número octal nnn

La expansión de parámetros (variables), la expansión aritmética, y la sustitución de
comandos se aplican al valor de PS1 cuando el intérprete de comandos es generado
también.
La secuencia de escape $ puede requerir más explicación. La shell de bash utiliza esta
secuencia para reproducir una característica de la shell Bourne originial (/bin/sh). El
intérprete de comandos por defecto de la shell Bourne es un dólar ($) para los usuarios
estándar y un signo (#) para el usuario root. Con la secuencia de escape $, un valor
predeterminado PS1 para todo el sistema puede utilizarse, imitándo esta conducta
original.
Al personalizar el intérprete de comandos de bash, el intérprete de comandos suele
verse más limpio si la variable PS1 está definida con un espacio al final.
46

La shell bash
Opciones y banderas de la shell de bash
Se utilizan dos comandos internos para configurar la conducta de la shell mediante las
opciones de shell. Uno es el comando set, el cual se utiliza para modificar la conducta
de shell mediante (por lo general) banderas de una letra, y el otro esshopt, usado para
configurar las opciones de la shell.
Banderas de la shell: el comando interno set
El comando set realiza una labor triple. Cuando se utiliza con la línea de comandos,
como suele ser el caso, el comando se utiliza para establecer, o anular las banderas de
shell. Observe el cuadro siguiente con las banderas más utilizadas y sus opciones.
Cuando se llamado sin argumentos, el comando set visualiza todas las variables de shell
y sus valores (como se describió en una lección anterior). El último uso del comando
incorporado se utiliza en la escritura de shell y por ahora puede hacerse caso omiso sin
ningún problema.
Table 1. Banderas de la shell que el comando interno set utiliza.
Bandera

Efecto

-f

Inhabilita la expansión de nombres de ruta (comodín)

-n

Lee comandos pero no los ejecuta (se usa para revisar sintaxis en los
scripts).
Establece la opción especificada. Algunas de las opciones más
comunes incluyen lo siguiente.
emacs
Emplea líneas de comandos con enlaces de teclas del estilo
emacs

-o
nombredeopción

ignoreeof
No sale de la shell cuando se lee EOF (CTRL-D)
vi
Usa enlaces clave de línea de comando del estilo vi

-v

Imprime comandos como se leen (útil para depurar scripts)

-x

Imprime comandos despues de aplicadas las expansiones (útil para
depurar scripts y examinar expansiones de la shell)

-C

No le permite a la shell reescribir archivos en redirección.

El comando set con la sintaxis normal de las opciones (tal como set -x) habilita la
bandera especificada. Para inhabilitar la bandera, remplace el guión (-) por un signo más
47

La shell bash
(+) (tal como set +x). La lista de opciones establecidas puede almacenarse en la variable
de shell $-.
Por ejemplo, a continuación, madonna temporalmente inhabilita el comodín de archivo
(habilitando la bandera de shell -f) y luego restaurando el comodín de archivo
(inhabilitando el mismo).
[madonna@station madonna]$ set -f
[madonna@station madonna]$ ls /etc/*.conf
ls: /etc/*.conf: No such file or directory
[madonna@station madonna]$ set +f
[madonna@station madonna]$ ls /etc/*.conf
/etc/aep.conf
/etc/lftp.conf
/etc/pnm2ppa.conf
/etc/aeplog.conf
/etc/libuser.conf
/etc/pwdb.conf
/etc/cdrecord.conf /etc/logrotate.conf /etc/resolv.conf
/etc/esd.conf
/etc/lpd.conf
/etc/rndc.conf
...

No se preocupe si no entiende aún los efectos de todas las banderas de shell. En su
lugar, asegúrese de saber cómo se utiliza el comando set para habilitar o inhabilitar una
bandera si es necesario. Si en una lección posterior le dijeran "esta acción puede
inhabilitarse al configurar la bandera -H de shell ", usted sabrá cómo hacerlo.
Opciones de la shell: el comando interno shopt
El comando bash también tiene una segunda serie de variables de configuración, las
cuales se conocen como "opciones de shell". Estas se establecen y se anulan mediante el
comando shopt donde shopt -s nombreopciónestablece la opción nombreopción, y
shopt -u nombreopción anula la opción. El comando shopt nombreopción visualiza el
estado actual de la opción, mientras que solo shopt visualiza todas las opciones de la
shell. Algunas de las opciones de shell más fáciles de entender están listadas en el
cuadro siguiente.
Table 1. Opciones de la shell bash
Opción
cdspell

Efecto
Intenta corregir palabras mal escritas de los nombres de directorios
cuando utiliza el comando incorporado cd.

expand_aliases Habilita alias de shell
extglob

Habilita sintaxis coincidente de patrones de comodines extendidos

nocaseglob

No considera el caso cuando se aplican comodines de archivo.

Lo anterior se presenta a manera de ejemplos. Revise la página de manual de bash(1)
para obtener una lista completa. A continuación, madonna examina el estado de la
opción de shell cdspell, lo habilita y luego el de cd en el directorio /etc con un deletreo
descuidado.
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash
6 la shell bash

Más contenido relacionado

La actualidad más candente

La actualidad más candente (16)

Unix 3.1
Unix 3.1Unix 3.1
Unix 3.1
 
Comandos básicos para la terminal de ubuntu
Comandos básicos para la terminal de ubuntuComandos básicos para la terminal de ubuntu
Comandos básicos para la terminal de ubuntu
 
Actividad 03.1 unix essentials file system basics.
Actividad 03.1 unix essentials  file system basics.Actividad 03.1 unix essentials  file system basics.
Actividad 03.1 unix essentials file system basics.
 
Linux comandos 1
Linux comandos 1Linux comandos 1
Linux comandos 1
 
Resumen línea comandos linux para bachillerato
Resumen línea comandos linux para bachilleratoResumen línea comandos linux para bachillerato
Resumen línea comandos linux para bachillerato
 
Habilidades de linux
Habilidades de linuxHabilidades de linux
Habilidades de linux
 
Comandos
ComandosComandos
Comandos
 
9 managing processes
9  managing processes9  managing processes
9 managing processes
 
[ES] Línea de Comandos GNU/Linux
[ES] Línea de Comandos GNU/Linux[ES] Línea de Comandos GNU/Linux
[ES] Línea de Comandos GNU/Linux
 
php
phpphp
php
 
Genesis Campos
Genesis CamposGenesis Campos
Genesis Campos
 
Manual php y_mysql
Manual php y_mysqlManual php y_mysql
Manual php y_mysql
 
01 practicas de laboratorio
01 practicas de laboratorio01 practicas de laboratorio
01 practicas de laboratorio
 
Scripts
ScriptsScripts
Scripts
 
Unidad 1 ciclo 5
Unidad 1 ciclo 5Unidad 1 ciclo 5
Unidad 1 ciclo 5
 
Practica en DOS
Practica en DOSPractica en DOS
Practica en DOS
 

Destacado

II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.com
II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.comII Congreso Ecommaster - Ecommerce Hacks - Slot4ever.com
II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.comEcommaster
 
Precios productos Amarillas Internet
Precios productos Amarillas InternetPrecios productos Amarillas Internet
Precios productos Amarillas InternetPepe Morales
 
Erkenntnistheoretische Beurteilung von Extreme Programming
Erkenntnistheoretische Beurteilung von Extreme ProgrammingErkenntnistheoretische Beurteilung von Extreme Programming
Erkenntnistheoretische Beurteilung von Extreme ProgrammingMarkus Harrer
 
Die ode von nirvana
Die ode von nirvanaDie ode von nirvana
Die ode von nirvanaYouxi Hao
 
Jetzthaus - ein Beispiel fuer innovative Planung und Erfahrung
Jetzthaus - ein Beispiel fuer innovative Planung und ErfahrungJetzthaus - ein Beispiel fuer innovative Planung und Erfahrung
Jetzthaus - ein Beispiel fuer innovative Planung und Erfahrungokradolta
 
Reglament Pelegrí Pi
Reglament Pelegrí PiReglament Pelegrí Pi
Reglament Pelegrí PiRafael Moral
 
Trakl
TraklTrakl
Traklvri
 
Ost 1 10274 84
Ost 1 10274 84Ost 1 10274 84
Ost 1 10274 84maishai75
 
Informe de pasantia de gabriel en bcv
Informe de pasantia de gabriel en bcvInforme de pasantia de gabriel en bcv
Informe de pasantia de gabriel en bcvmedicen_gabi
 
Solución poara trabajo en equipos horario extraescolar
Solución poara trabajo en equipos horario extraescolarSolución poara trabajo en equipos horario extraescolar
Solución poara trabajo en equipos horario extraescolarRobert Ortiz
 
Perry pakull datenbank entwickler auf dem prüfstand präsentation
Perry pakull datenbank entwickler auf dem prüfstand präsentationPerry pakull datenbank entwickler auf dem prüfstand präsentation
Perry pakull datenbank entwickler auf dem prüfstand präsentationTrivadis
 
Anexo fuentes-isabel
Anexo fuentes-isabelAnexo fuentes-isabel
Anexo fuentes-isabelolleria8
 
Lenguaje de programacion
Lenguaje de programacionLenguaje de programacion
Lenguaje de programacionEdwin
 

Destacado (20)

II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.com
II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.comII Congreso Ecommaster - Ecommerce Hacks - Slot4ever.com
II Congreso Ecommaster - Ecommerce Hacks - Slot4ever.com
 
Precios productos Amarillas Internet
Precios productos Amarillas InternetPrecios productos Amarillas Internet
Precios productos Amarillas Internet
 
GLONASS
GLONASSGLONASS
GLONASS
 
Erkenntnistheoretische Beurteilung von Extreme Programming
Erkenntnistheoretische Beurteilung von Extreme ProgrammingErkenntnistheoretische Beurteilung von Extreme Programming
Erkenntnistheoretische Beurteilung von Extreme Programming
 
Maniobra de heimlich
Maniobra de heimlichManiobra de heimlich
Maniobra de heimlich
 
WEB DEVELOPMENT
WEB DEVELOPMENTWEB DEVELOPMENT
WEB DEVELOPMENT
 
Die ode von nirvana
Die ode von nirvanaDie ode von nirvana
Die ode von nirvana
 
Jetzthaus - ein Beispiel fuer innovative Planung und Erfahrung
Jetzthaus - ein Beispiel fuer innovative Planung und ErfahrungJetzthaus - ein Beispiel fuer innovative Planung und Erfahrung
Jetzthaus - ein Beispiel fuer innovative Planung und Erfahrung
 
Clase 5 -resumen trabajo en equipo
 Clase 5 -resumen trabajo en equipo Clase 5 -resumen trabajo en equipo
Clase 5 -resumen trabajo en equipo
 
Reglament Pelegrí Pi
Reglament Pelegrí PiReglament Pelegrí Pi
Reglament Pelegrí Pi
 
Beisbol
BeisbolBeisbol
Beisbol
 
Trakl
TraklTrakl
Trakl
 
Ost 1 10274 84
Ost 1 10274 84Ost 1 10274 84
Ost 1 10274 84
 
Los hackers
Los hackersLos hackers
Los hackers
 
Informe de pasantia de gabriel en bcv
Informe de pasantia de gabriel en bcvInforme de pasantia de gabriel en bcv
Informe de pasantia de gabriel en bcv
 
Solución poara trabajo en equipos horario extraescolar
Solución poara trabajo en equipos horario extraescolarSolución poara trabajo en equipos horario extraescolar
Solución poara trabajo en equipos horario extraescolar
 
Las tabletas
Las tabletasLas tabletas
Las tabletas
 
Perry pakull datenbank entwickler auf dem prüfstand präsentation
Perry pakull datenbank entwickler auf dem prüfstand präsentationPerry pakull datenbank entwickler auf dem prüfstand präsentation
Perry pakull datenbank entwickler auf dem prüfstand präsentation
 
Anexo fuentes-isabel
Anexo fuentes-isabelAnexo fuentes-isabel
Anexo fuentes-isabel
 
Lenguaje de programacion
Lenguaje de programacionLenguaje de programacion
Lenguaje de programacion
 

Similar a 6 la shell bash

Similar a 6 la shell bash (20)

Semana 4 y_5_-_la_shell_bash
Semana 4 y_5_-_la_shell_bashSemana 4 y_5_-_la_shell_bash
Semana 4 y_5_-_la_shell_bash
 
Linux Programacion en Shell
Linux Programacion en ShellLinux Programacion en Shell
Linux Programacion en Shell
 
The linux shell. Shell Scripting desde 0
The linux shell. Shell Scripting desde 0The linux shell. Shell Scripting desde 0
The linux shell. Shell Scripting desde 0
 
Script
ScriptScript
Script
 
Script Y Comandos De Linux
Script Y Comandos De LinuxScript Y Comandos De Linux
Script Y Comandos De Linux
 
Shell script en linux
Shell script en linuxShell script en linux
Shell script en linux
 
Agilidad en shell de linux
Agilidad en shell de linuxAgilidad en shell de linux
Agilidad en shell de linux
 
Comandos
ComandosComandos
Comandos
 
Script presentacion
Script presentacionScript presentacion
Script presentacion
 
17 comandos basicoslinuxasoitson
17 comandos basicoslinuxasoitson17 comandos basicoslinuxasoitson
17 comandos basicoslinuxasoitson
 
[ES] Administración básica de GNU / Linux
[ES] Administración básica de GNU / Linux[ES] Administración básica de GNU / Linux
[ES] Administración básica de GNU / Linux
 
Conceptos básicos del shell
Conceptos básicos del shellConceptos básicos del shell
Conceptos básicos del shell
 
Curso Bash 1
Curso Bash 1Curso Bash 1
Curso Bash 1
 
Programación en Bash
Programación en BashProgramación en Bash
Programación en Bash
 
Julissa
JulissaJulissa
Julissa
 
Julissa
JulissaJulissa
Julissa
 
Unix JCRB
Unix JCRBUnix JCRB
Unix JCRB
 
Como instalar Unix(Johanna)
Como instalar Unix(Johanna)Como instalar Unix(Johanna)
Como instalar Unix(Johanna)
 
Comandos linux
Comandos linuxComandos linux
Comandos linux
 
El shell-bash
El shell-bashEl shell-bash
El shell-bash
 

Más de Juan Camilo

Instalación de un sistema Voip corporativo basado en asterisk
Instalación de un sistema Voip corporativo basado en asteriskInstalación de un sistema Voip corporativo basado en asterisk
Instalación de un sistema Voip corporativo basado en asteriskJuan Camilo
 
10 network applications
10 network applications10 network applications
10 network applicationsJuan Camilo
 
9 managing processes
9  managing processes9  managing processes
9 managing processesJuan Camilo
 
8 herramientas de procesos de string
8  herramientas de procesos de string8  herramientas de procesos de string
8 herramientas de procesos de stringJuan Camilo
 
7 standard io and pipes
7 standard io and pipes7 standard io and pipes
7 standard io and pipesJuan Camilo
 
5 the linux filesystem
5 the linux filesystem5 the linux filesystem
5 the linux filesystemJuan Camilo
 
4 file ownerships and permissions
4 file ownerships and permissions4 file ownerships and permissions
4 file ownerships and permissionsJuan Camilo
 
3 users and groups
3   users and groups3   users and groups
3 users and groupsJuan Camilo
 
2 filesystem basics
2 filesystem basics2 filesystem basics
2 filesystem basicsJuan Camilo
 

Más de Juan Camilo (11)

Instalación de un sistema Voip corporativo basado en asterisk
Instalación de un sistema Voip corporativo basado en asteriskInstalación de un sistema Voip corporativo basado en asterisk
Instalación de un sistema Voip corporativo basado en asterisk
 
10 network applications
10 network applications10 network applications
10 network applications
 
9 managing processes
9  managing processes9  managing processes
9 managing processes
 
8 herramientas de procesos de string
8  herramientas de procesos de string8  herramientas de procesos de string
8 herramientas de procesos de string
 
7 standard io and pipes
7 standard io and pipes7 standard io and pipes
7 standard io and pipes
 
5 the linux filesystem
5 the linux filesystem5 the linux filesystem
5 the linux filesystem
 
4 file ownerships and permissions
4 file ownerships and permissions4 file ownerships and permissions
4 file ownerships and permissions
 
3 users and groups
3   users and groups3   users and groups
3 users and groups
 
2 filesystem basics
2 filesystem basics2 filesystem basics
2 filesystem basics
 
11 suplemments
11 suplemments11 suplemments
11 suplemments
 
1 quick tours
1 quick tours1 quick tours
1 quick tours
 

Último

3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx
3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx
3. Pedagogía de la Educación: Como objeto de la didáctica.ppsxJuanpm27
 
Fichas de Matemática TERCERO DE SECUNDARIA.pdf
Fichas de Matemática TERCERO DE SECUNDARIA.pdfFichas de Matemática TERCERO DE SECUNDARIA.pdf
Fichas de Matemática TERCERO DE SECUNDARIA.pdfssuser50d1252
 
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMAL
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMALVOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMAL
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMALEDUCCUniversidadCatl
 
Manejo del Dengue, generalidades, actualización marzo 2024 minsa
Manejo del Dengue, generalidades, actualización marzo 2024 minsaManejo del Dengue, generalidades, actualización marzo 2024 minsa
Manejo del Dengue, generalidades, actualización marzo 2024 minsaLuis Minaya
 
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfTarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfManuel Molina
 
4º SOY LECTOR PART2- MD EDUCATIVO.p df PARTE
4º SOY LECTOR PART2- MD  EDUCATIVO.p df PARTE4º SOY LECTOR PART2- MD  EDUCATIVO.p df PARTE
4º SOY LECTOR PART2- MD EDUCATIVO.p df PARTESaraNolasco4
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfAlfredoRamirez953210
 
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxMonitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxJUANCARLOSAPARCANARE
 
cuadernillo de lectoescritura para niños de básica
cuadernillo de lectoescritura para niños de básicacuadernillo de lectoescritura para niños de básica
cuadernillo de lectoescritura para niños de básicaGianninaValeskaContr
 
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfTema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfDaniel Ángel Corral de la Mata, Ph.D.
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxYeseniaRivera50
 
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdf
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdfFichas de Matemática DE SEGUNDO DE SECUNDARIA.pdf
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdfssuser50d1252
 
DETALLES EN EL DISEÑO DE INTERIOR
DETALLES EN EL DISEÑO DE INTERIORDETALLES EN EL DISEÑO DE INTERIOR
DETALLES EN EL DISEÑO DE INTERIORGonella
 
FICHA DE MONITOREO Y ACOMPAÑAMIENTO 2024 MINEDU
FICHA DE MONITOREO Y ACOMPAÑAMIENTO  2024 MINEDUFICHA DE MONITOREO Y ACOMPAÑAMIENTO  2024 MINEDU
FICHA DE MONITOREO Y ACOMPAÑAMIENTO 2024 MINEDUgustavorojas179704
 
Técnicas de grabado y estampación : procesos y materiales
Técnicas de grabado y estampación : procesos y materialesTécnicas de grabado y estampación : procesos y materiales
Técnicas de grabado y estampación : procesos y materialesRaquel Martín Contreras
 

Último (20)

3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx
3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx
3. Pedagogía de la Educación: Como objeto de la didáctica.ppsx
 
Fichas de Matemática TERCERO DE SECUNDARIA.pdf
Fichas de Matemática TERCERO DE SECUNDARIA.pdfFichas de Matemática TERCERO DE SECUNDARIA.pdf
Fichas de Matemática TERCERO DE SECUNDARIA.pdf
 
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMAL
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMALVOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMAL
VOLUMEN 1 COLECCION PRODUCCION BOVINA . SERIE SANIDAD ANIMAL
 
Manejo del Dengue, generalidades, actualización marzo 2024 minsa
Manejo del Dengue, generalidades, actualización marzo 2024 minsaManejo del Dengue, generalidades, actualización marzo 2024 minsa
Manejo del Dengue, generalidades, actualización marzo 2024 minsa
 
Earth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversaryEarth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversary
 
DIA INTERNACIONAL DAS FLORESTAS .
DIA INTERNACIONAL DAS FLORESTAS         .DIA INTERNACIONAL DAS FLORESTAS         .
DIA INTERNACIONAL DAS FLORESTAS .
 
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdfTarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
Tarea 5_ Foro _Selección de herramientas digitales_Manuel.pdf
 
4º SOY LECTOR PART2- MD EDUCATIVO.p df PARTE
4º SOY LECTOR PART2- MD  EDUCATIVO.p df PARTE4º SOY LECTOR PART2- MD  EDUCATIVO.p df PARTE
4º SOY LECTOR PART2- MD EDUCATIVO.p df PARTE
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
 
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptxMonitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
Monitoreo a los coordinadores de las IIEE JEC_28.02.2024.vf.pptx
 
Sesión La luz brilla en la oscuridad.pdf
Sesión  La luz brilla en la oscuridad.pdfSesión  La luz brilla en la oscuridad.pdf
Sesión La luz brilla en la oscuridad.pdf
 
cuadernillo de lectoescritura para niños de básica
cuadernillo de lectoescritura para niños de básicacuadernillo de lectoescritura para niños de básica
cuadernillo de lectoescritura para niños de básica
 
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdfTema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
Tema 8.- Gestion de la imagen a traves de la comunicacion de crisis.pdf
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
 
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdf
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdfFichas de Matemática DE SEGUNDO DE SECUNDARIA.pdf
Fichas de Matemática DE SEGUNDO DE SECUNDARIA.pdf
 
VISITA À PROTEÇÃO CIVIL _
VISITA À PROTEÇÃO CIVIL                  _VISITA À PROTEÇÃO CIVIL                  _
VISITA À PROTEÇÃO CIVIL _
 
DETALLES EN EL DISEÑO DE INTERIOR
DETALLES EN EL DISEÑO DE INTERIORDETALLES EN EL DISEÑO DE INTERIOR
DETALLES EN EL DISEÑO DE INTERIOR
 
FICHA DE MONITOREO Y ACOMPAÑAMIENTO 2024 MINEDU
FICHA DE MONITOREO Y ACOMPAÑAMIENTO  2024 MINEDUFICHA DE MONITOREO Y ACOMPAÑAMIENTO  2024 MINEDU
FICHA DE MONITOREO Y ACOMPAÑAMIENTO 2024 MINEDU
 
Técnicas de grabado y estampación : procesos y materiales
Técnicas de grabado y estampación : procesos y materialesTécnicas de grabado y estampación : procesos y materiales
Técnicas de grabado y estampación : procesos y materiales
 
TL/CNL – 2.ª FASE .
TL/CNL – 2.ª FASE                       .TL/CNL – 2.ª FASE                       .
TL/CNL – 2.ª FASE .
 

6 la shell bash

  • 1. 1 La shell bash Capítulo 1 Introducción a Bash Conceptos clave • • • • La shell por defecto en Red Hat Enterprise Linux es la shell bash. La shell bash se puede utilizar de modo interactivo o como un lenguaje de escritura de gran alcance. Tras el arranque, bash ejecuta comandos hallados en el archivo ~/.bashrc, permitiéndole a los usuarios personalizar su shell. La shell bash guarda el historial de las líneas de comando ejecutadas. La líneas de comando se pueden recuperar desde el historial mediante varias expansiones de historial que comienzan por "!". La shell bash En Linux, la shell es el programa más utilizado. La shell es lo que usted ve cuando inicia sesión o cuando abre una terminal y lo que más usa para iniciar cada comando. Aunque hay una variedad de shells disponibles, todas siguen la misma conducta básica: escuchar los comandos del usuario, iniciar procesos como se especifica en los comandos e informar los resultados al usuario. La shell más utilizada en Linux es la shell bash, la cual es la shell por defecto en Red Hat Enterprise Linux. La shell bash no sólo es de fácil uso para tareas sencillas, sino también tiene capacidades de gran alcance para facilitar tareas complejas o incluso hacerlas posibles. Esta eficacia trae consigo complejidad, solo basta con dar un vistazo a la página bash del manual (que tiene mas de 4.500 líneas) para convencerse. Este cuaderno presentará muchas de estas capacidades de gran alcance. Shells interactivas vs. Scripts de shell La shell bash está diseñada para ser eficaz para dos tipos diferentes de uso. Usted ya está familiarizado con el uso del comando bash como una shell interactiva. Muchas de estas características de bash permiten a las personas escribir comandos de una manera más fácil y eficaz y gran parte de este cuaderno se enfocará en estas habilidades. La shell bash también está diseñada para ser un lenguaje de escritura de gran alcance. Los scripts de la shell bash son programas pequeños escritos mediante la misma sintaxis que se utiliza en la línea de comandos. Los scripts de shell permiten a los usuarios automatizar las acciones repetidas al combinar una serie de comandos. A diferencia de las shells interactivas, los scripts de shell suelen ejecutar una serie de comandos de modo no interactivo y muchas de estas características de la shell bash proveen una programación lógica (tales como ramas y bucles) para escribir scripts sofisticados. Al final de este cuaderno encontrará una introducción a la escritura de shell.
  • 2. 2 La shell bash Al continuar a través de este cuaderno, trate de tener en la mente estos dos usos diferentes de la shell bash. Algunas características de bash, tales como el historial de comandos, que pronto veremos, son casi inútiles en los scripts de shell. Otros rasgos, tales como la sustitución aritmética, pueden no parecer út¡les en la línea de comandos, pero pueden ser útiles en un script de shell. Si la utilidad de una característica de un bash no es de inmediato obvia, trate de verla en otro contexto. Shells de inicio En la práctica, los usuarios a veces necesitan iniciar una shell de modo manual. Cada vez que alguien inicie sesión o abra una terminal, una shell se inicia automáticamente. Sin embargo, a veces los usuarios desearían ejecutar una shell diferente u otra instancia de la misma shell. Dado que la shell es sólo "otro programa", nuevas shells pueden iniciarse desde la shell existente. La nueva shell se denomina subshell de la shell original. Cuando se sale de la subshell, el control vuelve a la shell original. En el siguiente ejemplo, madonna inicia una subshell bash, lista los procesos desde dentro de ésta para confirmar que las dos shells se están ejecutando y luego sale de la subshell. [madonna@station madonna]$ bash [madonna@station madonna]$ ps PID TTY TIME CMD 9750 pts/5 00:00:00 bash 9786 pts/5 00:00:00 bash 9814 pts/5 00:00:00 ps [madonna@station madonna]$ exit exit [madonna@station madonna]$ Cuando inicia una subshell bash, las diferencias aparentes entre la subshell y la shell padre son mínimas y se debe tener cuidado de seguir el rastro de la shell en la que se encuentra. El archivo ~/.bashrc Como parte de su inicialización, la shell bash buscará en el directorio de inicio del usuario un archivo titulado .bashrc. El archivo se emplea para personalizar la shell bash. Cuando la shell inicia, los comandos listados en el archivo se ejecutan como si fueran escritos en la línea de comandos. Técnicamente, la shell bash "lee" el archivo. Los conceptos relacionados con la lectura de archivos y la inicialización de shell se tratarán en detalle más adelante. Aquí, presentaremos rápidamente este sólo archivo para poder hacer uso de él en ejercicios posteriores. A continuación, madonna edita su archivo ~/.bashrc agregándole el comando cal, para que tras el arranque la shell bash se presente un calendario del mes actual. [madonna@station madonna]$ nano .bashrc ... (madonna appends a single line containing the command "cal") ... [madonna@station madonna]$ cat .bashrc
  • 3. 3 La shell bash # .bashrc # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi cal La usuaria madonna agregó esta única línea. Las líneas restantes se encuentran en un archivo por defecto ~/.bashrc de un usuario. Ahora, cada vez que madonna inicia una shell bash (por ejemplo, iniciando en una consola virtual o abriendo otra ventana de terminal), se presenta un calendario. [madonna@station madonna]$ bash August 2003 Su Mo Tu We Th Fr Sa -*// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [madonna@station madonna]$ exit Introducir Comandos Las shells interactivas repiten el ciclo de escuchar una línea de comandos, evalúan el comando solicitado, realizan todas las acciones solicitadas y muestran los resultados. La shell escucha al teclado de entrada y emplea la tecla de ENTER para reconocer el final de la entrada como en la siguiente ejecución del comando echo. [madonna@station madonna]$ echo "hello world" hello world Historial de comandos Como conveniencia para los usuarios de shells interactivas, el comando shell bash mantiene el historial de cada uno de los comandos escritos por el usuario y ofrece una variedad de formas para hacer que los comandos desde este historial estén a su alcance. La forma más fácil de ver el historial actual es mediante el comandohistory. [blondie@station blondie]$ history 1 ls -l /home/ 2 ls -ln /home/ 3 exit 4 exit 5 id ... 167 mv rhyme stuff/
  • 4. 4 La shell bash 168 169 170 171 172 ls -Rli exit exit history Como se muestra, el comando history entrega un historial de los comandos previamente escritos, con cada entrada precedida por un "número de historial". El comando history va hasta el final de la lista. Desde la línea de comandos, las teclas de dirección ARRIBA y ABAJO atraviesan pronto la lista de arriba a abajo, mientras que las teclas de dirección IZQUIERDA y DERECHA moverán el cursor para permitir al usuario editar un comando dado. Por ejemplo, si blondie quisiera luego ejecutar el comando ls -li, podría pulsar la tecla ARRIBA 5 veces y su intérprete de comandos llenaría con el comando ls -Rli. Podría entonces pulsar dos veces la tecla de dirección IZQUIERDA y RETROCESO para suprimir R de la línea de comandos seguido por la tecla ENTER. Mediante las teclas de flecha, los usuarios pueden rápidamente revisar, editar y ejecutar comandos tecleados anteriormente. Sustitución de historial Como una alternativa a las teclas de dirección, la shell bash también realiza "sustitución de historial", la cual se desencadena por el signo de exclamación. El siguiente cuadro resume la sintaxis de sustitución de historial más utilizada. Table 1. Sustitución de historial bash Sustitución Sintaxis !! Comando anterior !n Comando número n !-n El comando más reciente n !cmd El comando más reciente que comienza por cmd A manera de ejemplo de la sintaxis anterior, analice la siguiente salida (abreviada) cuando blondie ejecuta el comando history. [blondie@station blondie]$ history ... 161 ls 162 ls -il 163 ln rhyme hard_link 164 ls -il 165 chmod 660 rhyme 166 ls -il 167 mv rhyme stuff/ 168 ls -Rli 169 exit 170 171 exit 172 history
  • 5. 5 La shell bash El siguiente cuadro lista lo que blondie escribiría en la línea de comandos y el comando resultante que ejecutaría. Línea de comandos Comando resultante !! historial !165 chmod 660 rhyme !-5 ls -Rli !mv mv rhyme stuff/ Conservar el historial entre sesiones No sólo el comando shell bash mantiene un historial de comandos dentro de una sesión, sino que también conserva los historiales de comandos entre sesiones. Cuando la shell bash sale, entrega el historial actual del comando dentro de un archivo llamado .bash_history en un directorio de inicio del usuario. Tras el arranque, la shell inicializa el historial de comandos desde el contenido de este archivo. ¿Qué repercusión tienen estas shells interactivas múltiples (pertenecientes a un mismo usuario) al ejecutar al mismo tiempo? Puesto que el historial solo se ha guardado en el disco cuando la shell sale, los comandos ejecutados en un proceso bash no están disponibles en el historial de comandos de un procesobash ejecutado simultáneamente. Además, la última shell al salir sobrescribirá las historias de las shells que salieron anteriormente. Si está establecido así, las siguientes variables configuran los detalles de cómo se guarda el historial de comandos. Table 1. Variables del historial de comandos de shell bash Variable Valor predeterminado Efectos HISTFILE ~/.bash_history El archivo en el cual el historial de comandos se guarda al salir y desde el cual se inicializa al arrancar. HISTFILESIZE 1000 El archivo HISTFILE se truncará a este tamaño en el arranque. HISTSIZE 1000 El número máximo de comandos que se escribrirán al salir en el archivoHISTFILE. Trucos del historial de comandos La shell bash ofrece muy pocas técnicas para acceder previamente los comandos tecleados (o elementos del mismo).
  • 6. 6 La shell bash ESC-. y ALT-. El último símbolo de la línea de comandos tecleados anteriormente puede recuperarse con cualquiera de las dos secuencias de teclas mencionadas anteriormente. Una vez aprendido, este truquito suele ser muy útil. El último simbolo de un comando suele representar el objeto que alguien está manipulando. Por ejemplo, alguien podría hacer un directorio y enseguida ejecutar cd en éste o editar un archivo e inmediatamente querer utilizar chmod para cambiar sus permisos. Si la secuencia clave se repite, la shell bash continuará el ciclo a través de los últimos símbolos de las primeras líneas de comando. CTRL-R Esta secuencia clave imita a !cmd en espíritu. El texto tecleado después de CTRL-R coincide con los comandos tecleados anteriormente con la ventaja de que las líneas de comandos coincidentes se ven de modo inmediato al teclear el texto. Usted también tiene la oportunidad de editar la línea recuperada (utilizando las teclas de dirección IZQUIERDA y DERECHA u otros golpes de teclado de edición de líneas de comando) antes de ejecutar el comando. fc El comando fc permite a los usuarios "arreglar" el comando escrito anteriormente al abrir el editor por defecto del usuario (por defecto vi) con el comando anterior escrito como texto. Tras salir del edtor (presumiblemente después de editar de alguna forma el comando), el nuevo texto se ejecutará de inmediato. Para aquellos expertos en salir del editor rápidamente, el comando es muy útil. Ejemplos Uso del historial de comandos para acortar el ciclo "editar/compilar/ejecutar" Con frecuencia, los programadores de lenguajes compilados tales como C suelen hallarse en un ciclo repetitivo: editar un archivo, compilarlo y luego ejecutar el programa. A continuación, madonna edita un archivo que contiene un programa pequeño C y luego lo compila con el compilador C gcc. Después de ejecutar el programa, decide hacer algunos cambios. Hace entonces uso del historial de comandos para agilizar el proceso. [madonna@station madonna]$ nano hello.c [madonna@station madonna]$ cat hello.c #include "stdio.h" int main(void) { printf("hello worldn"); return 0;
  • 7. 7 La shell bash } [madonna@station madonna]$ gcc -o hello hello.c [madonna@station madonna]$ ./hello hello world [madonna@station madonna]$ !n nano hello.c (... madonna edits the file, replacing the string "hello world" with "hello dolly" ...) [madonna@station madonna]$ !c cat hello.c #include "stdio.h" int main(void) { printf("hello dollyn"); return 0; } [madonna@station madonna]$ !g gcc -o hello hello.c [madonna@station madonna]$ !. ./hello hello dolly Observe que la shell bash imprime el comando seleccionado desde el historial de madonna antes de ejecutar el comando. Uso de ESC. Ahora madonna quisiera crear un subdirectorio bin, establece sus permisos para que sólo ella pueda acceder a éste y mover su archivo ejecutable hello en él. Usa la secuencia de teclas ESC-. para agilizar el proceso. [madonna@station [madonna@station [madonna@station [madonna@station hello madonna]$ madonna]$ madonna]$ madonna]$ mkdir bin chmod 700 <ESC-.> mv hello <ESC-.> ls <ESC-.> Quizas no es el ejemplo más interesante porque bin es un directorio muy pequeño para teclear de todas maneras. Sin embargo, si hubiera sido el directorio /usr/lib/perl5/ven or_perl/5.8.0/HTML/, los golpes de teclado grabados serían impresionantes. Inhibición del historial de comandos Madonna es desconfiada y preferiría que su historial de comandos fuera almacenado en el disco al salir de la shell. Suprime su archivo del historial y crea un enlace blando con el mismo nombre que apunta al nodo de dispositivo /dev/null. [madonna@station madonna]$ rm .bash_history
  • 8. 8 La shell bash [madonna@station madonna]$ ln -s /dev/null .bash_history [madonna@station madonna]$ ls -l .bash_history lrwxrwxrwx 1 madonna madonna 9 Aug 26 16:35 .bash_history -> /dev/null [madonna@station madonna]$ cat .bash_history [madonna@station madonna]$ Madonna ahora puede usar el historial de comandos de bash para recuperar los comandos utilizados en la shell actual, pero ningún historial de comandos se almacenará entre las instancias de shell. Ejercicios en línea Lab Exercise Objetivo: Personalizar su archivo ~/.bashrc para mantener un registro de cuándo se inician las shells. Estimated Time: 10 mins. Especificaciones 1. Use un editor de texto para modificar el archivo .bashrc desde su directorio de inicio, agregando la siguiente línea al final del archivo. 2. date >> .bash_timestamps 3. Observe el archivo .bash_timestamps, y confirme si se agrega una nueva marca de tiempo cada vez que inicia una nueva shell bash. 4. De nuevo, mediante un editor de texto, agregue una línea de comentario a su archivo .bashrc que describa brevemente por qué el comando de fecha fue agregado e incluya su nombre de usuario como la persona que hizo la modificación. Deliverables A title Question 1 1. En su directorio de inicio, un .bashrc modificado que agregue una marca de tiempo al archivo .bash_timestamps cada vez que se inicie una shell bash. 2. El archivo .bashrc debe también contener una línea de comentario que incluya su nombre de usuario.
  • 9. 9 La shell bash Capítulo 2 Listas de comandos y scripts Conceptos clave • • • • Comandos múltiples se pueden separar con un ;. Tras la salida, cada comando devuelve un entero a su padre denominado valor de retorno. La variable de shell $? se expande al valor de retorno de un comando ejecutado previamente. && y || separan condicionalmentecomandos múltiples. Ejecución de comandos múltiples La shell bash permite a los usuarios unir comandos múltiples en una sola línea de comandos separando los comandos con un ;. (en inglés es igual; las frases independientes se separan con un punto y coma). Veamos un ejemplo: [elvis@station applnk desktop-menus Xmodmap fs Xresources gdm xserver lbxproxy [elvis@station elvis]$ cd /etc/X11; ls prefdm sysconfig proxymngr twm xorg.conf.backup xorg.conf.wbx rstart X xorg.conf.works serverconfig xdm XftConfig.README-OBSOLETE starthere X11]$ xorg.conf xinit xkb xsm El efecto es idéntico al escribir comandos en líneas separadas. [elvis@station [elvis@station applnk desktop-menus Xmodmap fs Xresources gdm xserver lbxproxy [elvis@station elvis]$ cd /etc/X11 X11]$ ls prefdm sysconfig proxymngr twm xorg.conf.backup xorg.conf.wbx rstart X xorg.conf.works serverconfig xdm XftConfig.README-OBSOLETE starthere X11]$ xorg.conf xinit xkb xsm La única diferencia entre los dos enfoques es que no se tiene la oportunidad de examinar el efecto del primer comando antes de que el segundo comando se ejecute. Muy pocas veces existe la necesidad real de ejecutar comandos múltiples desde una solo línea de comandos, pero suele ser conveniente combinar los comandos. Ejecución de comandos en una subshell
  • 10. 10 La shell bash La shell bash permite a los usuarios la fácil ejecución de comandos en una subshell, delimitando el comando entre paréntesis. Considere el siguiente ejemplo: [elvis@station applnk desktop-menus Xmodmap fs Xresources gdm xserver lbxproxy [elvis@station elvis]$ (cd /etc/X11; ls) prefdm sysconfig xorg.conf.backup proxymngr twm xorg.conf.wbx rstart X xorg.conf.works serverconfig xdm XftConfig.README-OBSOLETE starthere elvis]$ xorg.conf xkb xinit xsm A primera vista, la conducta parece idéntica a la del ejemplo anterior. Una mirada más de cerca revela una diferencia sutil pero importante. En el primer ejemplo, cuando los comandos se separan apenas por un punto y coma, los comandos se ejecutan en la shell actual. El intérprete de comandos de bash revela que, después de ejecutados los comandos, la shell del directorio de trabajo actual ha cambiado a /etc/X11 como resultado del comando cd. En el ejemplo anterior, al delimitar los comandos entre paréntesis, el directorio de shell actual no cambia. Cuando bash encuentra un paréntesis en la línea de comandos, éste genera un nuevo proceso hijobash (llamado subshell) y ejecuta los comandos dentro de la subshell. Después de ejecutarlos, la subshell sale y el usuario queda en la shell original (shell sin cambios). El efecto es parecido a la siguiente secuencia de comandos. [elvis@station [elvis@station applnk desktop-menus Xmodmap fs Xresources gdm xserver lbxproxy [elvis@station exit [elvis@station elvis]$ bash elvis]$ cd /etc/X11; ls prefdm sysconfig proxymngr twm xorg.conf.backup xorg.conf.wbx rstart X xorg.conf.works serverconfig xdm XftConfig.README-OBSOLETE starthere X11]$ exit xorg.conf xinit xkb xsm elvis]$ La subshell se inicia manualmente al ejecutar el comando bash. Los comandos se ejecutan ahora en la subshell. Al terminar, se sale de la subshell. Ahora que elvis está de nuevo en su shell original, las modificaciones en la subshell (tales como el cambio en el directorio de trabajo actual) han quedado atrás. ¿Por qué podría alguien desear ejecutar un comando en una subshell? Las subshells se utilizan para evitar efectos secundarios. Lo que suceda en la subshell no debería tener efecto en el entorno original de la shell (como en inglés, lo que está entre paréntesis no debe cambiar la frase que lo rodea).
  • 11. 11 La shell bash Introducción a los scripts de shell La clave para usar Red Hat Enterprise Linux de modo efectivo es la automatización. Un buen administrador de Linux debe ser en realidad extremadamente perezoso cuando se trata de hacer algo aburridor o repetitivo. Las secciones anteriores ilustraron la manera de encadenar comandos para ejecutar de modo consecutivo o simultáneo en lugar de esperar a que el comando termine antes de teclear el próximo. También le introdujeron a las características del historial de bash y le mostraron cómo referirse a comandos tecleados previamente para que sólo tenga que escribirlos una vez. Sin embargo, aún falta una parte importante de la caja de herramientas del administrador del sistema: la escritura de scripts. Un script, en su forma más simple, es un texto con una lista de comandos en él. Los comandos se envían a través de un programa específico llamado intérprete, el cual ejecuta un comando a la vez. Este intérprete suele ser la shell bash (conocida como /bin/bash o /bin/sh) y cada comando es un comando común de Linux. Otros intérpretes permiten utilizar lenguajes de programación de gran alcance como Perl, Python y Ruby. Antes de comenzar a escribir sus propios scripts hay algunas cosas importantes que recordar: • • • La primera línea de su script debe especificar a qué intérprete enviar las instrucciones. Esto se hace con una cadena especial llamada "shebang" (pronunciada "shuh-bang"), la cual se ve así: #!. A la shebang le sigue un nombre de un intérprete para este script. Así, por ejemplo, para usar bash como su intérprete usted debería usar #!/bin/sh o #!/bin/bash. La mayoría de los scripts sólo usan #!/bin/sh. Al referirse al intérprete como #!/bin/bash se habilitan otras características, pero se limita la compatibilidad del script con los sistemas antiguos de Unix y rara vez es necesario. Antes de ejecutar un script, usted debe habilitar el permiso "ejecutable" en él (de lo contrario, es sólo un archivo de texto). El comando para esto es chmod u+x <scriptname>. Le otorga (y sólo a usted) permiso para ejecutar este script justo como usted haría con otro comando. El comando chmod se tratará en detalle más adelante en esta clase. Si creó un script llamado foo.sh en su directorio de inicio y justo después tecleó foo.sh obtendría el mensaje de error "no existe tal directorio o archivo". Esto se debe a que cuando teclea un comando hay una serie de directorios en donde Linux busca ese comando. Estos directorios se conocen colectivamente como su RUTA y, por razones de seguridad, su RUTA nunca incluye el directorio actual. Para resolver este problema tiene dos alternativas: 1. Usted puede especificar de modo explícito la ubicación del script al teclear ~/foo.sh o ./foo.sh ("." siempre se refiere al directorio actual). 2. Puede colocar el script en un directorio que sea parte de su RUTA. Los usuarios que no son root no tienen permiso para colocar archivos en la mayoría de estos directorios, pero todos los usuarios tienen un bin personal, al cual pueden escribir en su directorio de inicio. Por lo tanto,
  • 12. 12 La shell bash si foo.sh fuera movido a ~/bin se podría ejecutar al teclear simplemente foo.sh en la línea de comandos. Esta es la técnica preferida. aprenderá más acerca de la RUTA en capítulos siguientes. Veamos un simple ejemplo. Suponga que usted es un administrador que necesita ver con frecuencia qué usuarios han iniciado sesión en el sistema. Esta información puede obtenerse al ejecutar el comando w (sí, eso es todo) pero mientras esto proporciona un buen resumen de quién ha iniciado sesión, no imprime la hora en la que se tomó esta instantánea de la actividad del usuario. Otro comando, llamado date imprime la fecha y hora actual, pero no la información del usuario. Si solo usted pudiera combinar esos dos comandos... Suponga que creó un script llamado wdate.sh en su directorio personal bin: [student@station ~]$ cat ~/bin/wdate.sh #!/bin/sh date w [student@station ~]$ chmod u+x ~/bin/wdate.sh [student@station ~]$ wdate.sh Thu Jul 14 12:13:54 PDT 2005 12:13:54 up 2 days, 12:50, 8 users, USER TTY FROM student_a tty1 student tty2 :0.0 /bin/sh/home/student/bin/wdate.sh load average: 0.35, 0.27, 0.18 LOGIN@ IDLE JCPU PCPU WHAT Mon23 ?xdm? 2:43m 3.06s /bin/bash Tue17 0.00s 2.19s 0.00s [student@station ~]$ Observe que el script había sido colocado en ~/bin y era ejecutable antes de ejecutarse como un comando normal. Al ejecutar date seguido por w, ¡nos da dos comandos por el precio de uno! Obviamente, este script podría luego modificarse para ejecutar un número arbitrario de comandos seguidos. De hecho, los scripts pueden ser mucho más eficaces que apenas una lista de comandos y pueden ser programas complejos en su propio derecho. El material complementario de esta lección describe técnicas avanzadas para scripts y pueden habilitarse a discreción de su instructor. Por ahora, concéntrese en dominar los scripts básicos como una valiosa técnica de almacenamiento. La regla de oro del administrador es que si usted tiene que hacer una tarea más de dos veces,¡haga un script! Valores de retorno Cada proceso en Linux tiene un ciclo de vida. Todos los procesos comienzan a solicitud de otro proceso (a menudo shell). El proceso solicitado se denomina padre, y el proceso recién nacido el hijo. El proceso hijo suele realizar sus deberes (incluyendo generar sus propios hijos), y luego elige morir. Un proceso de salida deja atrás una pequeña parte de información cuando muere, llamado el valor de retorno del proceso o estatus de salida. El proceso padre es responsable de reunir los valores de retorno de los hijos muertos.
  • 13. 13 La shell bash Los valores de retorno vienen en forma de enteros los cuales van de 0 a 255. Los programas pueden escoger líbremente el valor al salir [1]. A menudo, lo que significan las implicaciones por valores de retorno son parte de una interfaz de un programa bien definido y están documentadas en la página man del programa, (si no está familiarizado con el comandodiff, la sección de "DIAGNÓSTICO" de su página del manual ofrece un ejemplo). Una convención de Linux (y Unix) es que un programa devuelve en 0 para implicar "éxito" en lo que estaba intentando hacer, y un valor de retorno de no cero que implica algun tipo de error. La shell bash almacena el valor de retorno del comando ejecutado anteriormente en una variable especial llamada ?. Infortunadamente, no hemos descrito aún todas las variables de shell (eso sigue luego), pero observemos que el valor de esta variable (por ejemplo, el valor de retorno del programa ejecutado antes), puede examinarse con el comando echo $?. En el siguiente ejemplo, el comando ls se utiliza para examinar los permisos del archivo /etc/passwd. Dado que el comando "funciona", el comando ls devuelve un valor de retorno de 0. [elvis@station elvis]$ ls -l /etc/passwd -rw-r--r-1 root root 3694 Aug 15 16:26 /etc/passwd [elvis@station elvis]$ echo $? 0 En contraste, los siguientes ejemplos muestran cómo responde el comando ls al listar un archivo que no existe. [elvis@station elvis]$ ls -l /etc/password ls: /etc/password: No such file or directory [elvis@station elvis]$ echo $? 1 Dado que el comando "no funcionó", devolvió un valor de retorno de 1. Devolver un 0 de éxito y un 1 cuando se presenta cualquier tipo de error, es una conducta normal. Si una página man del programa no menciona otra cosa, generalmente se puede asumir esta conducta. Ejecución de comandos múltiples de modo condicional La shell bash usa &&y || para unir dos comandos de modo condicional. Cuando los comandos se unen de este modo, el primero siempre se ejecutará. El segundo comando puede que se ejecute o no dependiendo del valor de retorno del primer comando. Por ejemplo, un usuario puede desear crear un directorio y luego mover un nuevo archivo dentro de ese directorio. Si la creación del directorio fracasa, entónces no hay razón para mover el archivo. Los dos comandos pueden acoplarse de la siguiente forma. [elvis@station elvis]$ echo "one two three" > numbers.txt [elvis@station elvis]$ mkdir /tmp/boring && mv numbers.txt /tmp/boring [elvis@station elvis]$ ls
  • 14. 14 La shell bash Al acoplar los dos comandos con &&, el segundo comando sólo ejecutará el primer comando que tuvo éxito (por ejemplo, tuvo un valor de retorno de 0). Esto es similar a la operación "and" que se encuentra en varios lenguajes de programación. En el ejemplo anterior, el comando mkdir tuvo éxito y luego el archivo se movió. ¿Qué sucedería si el comando mkdir fracasara? [elvis@station elvis]$ echo "one two three five seven eleven" > primes.txt [elvis@station elvis]$ mkdir /tmp/mostly/boring && mv primes.txt /tmp/mostly/boring mkdir: cannot create directory `/tmp/mostly/boring': No such file or directory [elvis@station elvis]$ ls primes.txt Dado que el comando mkdir fracasó (el directorio /tmp/mostly no existá, por lo tanto el directorio /tmp/mostly/boring no se pudo crear), bash no trató de ejecutar el comando mv. Igualmente, los comandos múltiples pueden combinarse con ||. En este caso, bash ejecutará el segundo comando sólo si el primer comando "fracasa"(tiene un valor de retorno diferente a cero). Esto es igual al operador "or" que se encuentra en lenguajes de programación. En el siguiente ejemplo, elvis intenta cambiar los permisos en un archivo. Si el comando fracasa, un mensaje para ese efecto se imprime en la pantalla. [elvis@station elvis]$ chmod 600 /tmp/boring/numbers.txt || echo "chmod failed." [elvis@station elvis]$ chmod 600 /tmp/mostly/boring/primes.txt || echo "chmod failed" chmod: failed to get attributes of `/tmp/mostly/boring/primes.txt': No such file or directory chmod failed En el primer caso, el comando chmod tuvo éxito, y no se imprimió ningún mensaje. En el segundo caso, el comando chmod fracasó (porque el archivo no existía) y apareció el mensaje "chmod failed" (aparte del mensaje de error estándar de chmod). Ejemplos Echoing $? twice El usuario elvis acaba de aprender sobre los valores de retorno, y está examinando los valores de retorno de varios comandos. Después de ejecutar (sin éxito) el comando ls, encuentra que, como era de esperar, la variable de bash ? contiene 1. Al examinar la variable otra vez, se da cuenta que ahora contiene un 0. ¿Qué hizo cambiar el valor? [elvis@station elvis]$ ls -l /etc/password ls: /etc/password: No such file or directory [elvis@station elvis]$ echo $? 1 [elvis@station elvis]$ echo $?
  • 15. 15 La shell bash 0 Recuerde que la variable de bash ? contiene el valor de retorno de los comandos ejecutados más recientemente. En el primer caso, éste contenía el valor de retorno (sin éxito) del comando ls. En el segundo caso, éste contenía el valor de retorno del comando echo (con éxito). Visualización de recordatorios El usuario ahora quiere desarrollar un esquema en donde pueda dejar recordatorios y que automáticamente aparezcan al iniciar una shell. Crea un archivo en el directorio de inicio llamado reminders con el texto brush your teeth y agrega la siguiente línea a su archivo ~/.bashrc. cat /home/elvis/reminders Luego prueba su configuración de modo manual iniciando una nueva shell bash. [elvis@station elvis]$ echo "brush your teeth" > reminders [elvis@station elvis]$ nano .bashrc [elvis@station elvis]$ cat .bashrc # .bashrc # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi cat reminders [elvis@station elvis]$ bash brush your teeth [elvis@station elvis]$ exit exit [elvis@station elvis]$ Todo parece funcionar bien, hasta que elvis sigue su consejo de limpieza y borra su archivo reminders. La próxima vez que inicia una shell se encuentra con lo siguiente: [elvis@station elvis]$ bash cat: reminders: No such file or directory [elvis@station elvis]$ Dándose cuenta que le gustaría ejecutar el comando cat sólo si el archivo reminders existe, edita la línea que agregó a su archivo .bashrc con lo siguiente: ls reminders > /dev/null && cat reminders
  • 16. 16 La shell bash Ahora el comando cat sólo se ejecutará si el comando ls tiene éxito, porque el archivo reminders existe, (¿hay una mejor forma de hacer esto? Sí, pero aún no hemos aprendido lo suficiente para hacerlo.) Ejercicios en línea Lab Exercise Objetivo: Ejecutar comandos dentro de una subshell. Estimated Time: 10 mins. Especificaciones 1. Agregue una sola línea al final del archivo .bashrc en su directorio de inicio. La línea debe ejecutar los comandos cd /usr y ls en una sola subshell , (al ejecutarla, el directorio de trabajo actual de su shell no se afectará.) Si se implementa correctamente, al iniciar una nueva shell debería ver una salida similar a la siguiente: [elvis@station elvis]$ bash bin etc include lib dict games kerberos libexec [elvis@station elvis]$ local sbin share src tmp X11R6 Deliverables A title Question 1 1. Un archivo ~/.bashrc cuya última línea ejecute los comandos cd /usr y ls en una sola subshell. Limpieza Una vez obtenga la calificación, restaure su archivo ~/.bashrc al estado original. Capítulo 3 Variable de bash Conceptos clave • • Las variables de la shell se asignan mediante una sintaxis A=apple. Las variables se examinan ("desreferencian") con el caracter $ como en echo $A.
  • 17. 17 La shell bash • • • En el nivel de kernel, cada proceso tiene una colección de variables de entorno que los procesos hijos heredan. El comando export convierte una variable de shell en una variable de entorno. Los comandos set y env listan las variables de shell y las variables de entorno, respectivamente. Conceptos básicos de la variable de shell La shell bash le permite a los usuarios establecer y hacer referencia a las variables de shell. Una variable de shell es simplemente un valor con nombre que la shell recuerda. Las variables de shell se pueden utilizar en comandos y scripts de shell y pueden también referenciarse en programas como opciones de configuración. Por ejemplo, el cliente de correo electrónico mutt ejecuta un editor externo al escribir un mensaje. Por defecto este editor esvi. Sin embargo, antes de ejecutar vi comprobará si una variable llamadaEDITOR se ha establecido. Si se ha establecido, entonces el comando definido por EDITOR se utiliza en lugar de vi. La mayoría de los programas que lanzan editores externos funcionan del mismo modo. Hay dos tipos de variables de shell: variables locales y variables de entorno. Una variable local existe solo dentro de la shell en la cual se crea. Las shells hijas heredan las variables de entorno como cuando se lanza una terminal después de iniciar sesión. Primero, veremos cómo definir una variable local, luego hablaremos acerca de cómo definir variables de entorno incluyendo la bash misma. El configurar las variables locales es bastante sencillo. En el siguiente ejemplo, prince establecerá la variable A con el valor apple. [prince@station prince]$ A=apple Si usted sigue, asegúrese de no dejar ningún espacio a los lados del signo =. Ahora la shell se "cuelga"a esta asociación por todo el tiempo que exista la shell (o hasta que se anule explícitamente, ver a continuación). Cada vez que prince quiera usar el valor "apple", puede usar la variable A en su lugar, iniciando la variable con el signo ($), como en el comando echo mostrado abajo. Esto se llamadesreferenciar la variable A. [prince@station prince]$ echo $A apple La variable se puede utilizar en cualquier parte de la línea de comandos (o en los scripts de shell). ¿Qué sucede si prince, en lenguaje colorido, decidiera escribir unas cuantas líneas acerca de las manzanas (o apples en inglés) y las almacenara en un archivo llamado ode_to_apple.txt. La siguiente línea podría ayudarlo a empezar: [prince@station prince]$ echo "Oh, I like them squishy" >> ode_to_$A.txt [prince@station prince]$ ls
  • 18. 18 La shell bash ode_to_apple.txt Cuando la shell bash examinó la línea de comandos, remplazó $A por apple. Estos son los conceptos básicos de las variables de shell. Las variables se establecen y se configuran con una sintaxis VAR=valor y se desreferencian con una sintaxis $VAR. Detalles de la variable de shell ¿Qué puede utilizarse como nombres de variables? Los nombres de variables pueden ser cualquier cadena de caracteres alfanuméricos (A-Z, a-z, 0-9), y el guión bajo (_), pero no pueden comenzar por un número. Las variables de shell distinguen mayúsculas de minúsculas, como se muestra a continuación. [prince@station prince]$ B=banana [prince@station prince]$ echo $B is my favorite fruit banana is my favorite fruit [prince@station prince]$ echo $b is my favorite fruit is my favorite fruit En el primera impresión en pantalla, $B fue remplazado por el valor banana. ¿Cómo fue desreferenciado $b? Si se le pide a la shell desreferenciar una variable no establecida, ésta remplaza la referencia de la variable con una cadena vacía (en otras palabras, con nada). Dado que b se considera como una variable diferente a B, y que la variable b nunca ha sido asignada, la shell remplaza la referencia $b con nada. Por protocolo, las variables suelen definirse con mayúsculas, pero esto no es más que protocolo. ¿Cuál puede ser el valor de la variable? Cualquier cosa. El truco se presenta en la asignación. Cuando se asignan las variables, la sintaxis es nombre=valor, sin dejar espacios. ¿Qué sucedería si prince quisiera que la variable FRUIT apuntara a la frase mushy bananas? [prince@station prince]$ FRUIT=mushy bananas -bash: bananas: command not found Nos hemos tropezado con una sintaxis avanzada para configurar las variables, es decir nombre=valor comando, el cual establece la variable name sólo para la ejecución del comando especificado. La shellbash obedientemente estableció la variable FRUIT en el valor mushy y fue a ejecutar el comando bananas, con resultados esperables. Pero esto no es lo importante, lo importante es que si quiere establecer una variable a un valor que contenga espacios, debe incluir el valor entre comillas. [prince@station prince]$ FRUIT="mushy bananas" [prince@station prince]$ echo $FRUIT is my favorite fruit mushy bananas is my favorite fruit Con esta modificación, prince obtiene la conducta correcta desde la shell bash, si no la gramática inglesa correcta.
  • 19. 19 La shell bash Cuando se desreferencian las variables, el nombre de la variable puede marcarse con corchetes {}, si es necesario. Por ejemplo, ¿qué sucedería si arriba, prince hubiera querido guardar su poema dentro de un archivo llamado apple_ode.txt? El ensaya el primer método obvio, en el mismo directorio como se muestra arriba. [prince@station prince]$ echo $A apple [prince@station prince]$ echo "Oh, I like them squishy" > $A_ode.txt [prince@station prince]$ ls ode_to_apple.txt ¿Dónde está el archivo apple_ode.txt? Un par de cosas han conspirado contra prince. Primero, la shell bash desreferenció el nombre correcto de variable, pero no el que prince quería. ¿De qué puede estar compuesta una variable? De caracteres alfanuméricos y minúsculas. La shell bash apuntó a la variable (sin inicializar) A_ode (a nada) y creó el archivo resultante .txt. En segundo lugar, debido a que .txt comienza por un ., es un "archivo oculto", así como ls -a lo revela. [prince@station prince]$ ls -a . .bash_profile .gtkrc .. .bashrc .kde .bash_history .gnome-desktop ode_to_apple.txt .bash_logout .gnupg .pgpkey [prince@station prince]$ cat .txt Oh, I like them squishy .plan .txt .viminfo .xauthizv2EF El usuario prince puede salir de esta situación utilizando corchetes para delimitar el nombre deseado de la variable. [prince@station prince]$ echo "Oh, I like them squishy" > ${A}_ode.txt [prince@station prince]$ ls apple_ode.txt ode_to_apple.txt Utilizar corchetes para delinear nombres de variable siempre es correcto y en algunos casos, es necesario. Al terminar con una variable, la variable se puede desligar de su valor con el comando unset. [prince@station prince]$ unset A [prince@station prince]$ echo $A [prince@station prince]$ Variables de Bash El siguiente cuadro lista algunas variables que se establecen automáticamente con la shell bash. Estas variables son de sólo lectura y no pueden ser configuradas por el usuario.
  • 20. 20 La shell bash Table 1. Variables Bash de sólo lectura Variable Se expande hasta ? El estatus de salida del comando ejecutado más recientemente - Opciones de banderas de la shell actualmente activadas $ Id (pid) del proceso de la shell actual ! Id (pid) del proceso del comando secundario más reciente _ Último símbolo del comando anterior PPID Id (pid) del proceso padre de la shell. SHELLOPTS Lista separada por comas de las opciones de shell actual como lo informó el comando set -o. UID El userid del usuario actual Estas variables son establecidas por la shell para proveer información. Estas no se pueden reasignar por el usuario, así como prince lo descubre a continuación. [prince@station prince]$ echo $SHELLOPTS braceexpand:emacs:hashall:histexpand:history:interactivecomments:monitor [prince@station prince]$ SHELLOPTS=foo -bash: SHELLOPTS: readonly variable Las siguientes variables son inicializadas por la shell bash, pero pueden ser reasignadas. Table 2. Variables Bash preasignadas Variable Se expande hasta BASH_VERSION La versión actual bash HOSTNAME El nombre del host DNS de la máquina actual OLDPWD El directorio de trabajo anterior PWD The current working directory RANDOM Un número aleatorio entre 0 y 32767 SECONDS El número de segundos desde que la shell se inició Variables de entorno El configurar y resolver variables debería ser bastante sencillo, (siempre y cuando se acuerde de los espacios). Ahora presentaremos un concepto un poco más sutil y mucho más útil: variables de entorno. Así como la shell bash permite asignar parejas de valores-nombre llamados variables de shell, el kernel de Linux permite a cualquier proceso definir las parejas nombre-valor
  • 21. 21 La shell bash llamadas variables de entorno. Estas variables son una parte del proceso almacenado en el kernel, simplemente como el id del proceso, el id del usuario y el directorio actual de trabajo son parte del proceso. Lo más importante es que cada vez que se inicie un proceso (tal como la shell bash iniciando el comando ls), las variables de entorno son heredadas por el proceso hijo. Esto le permite a los usuarios utilizar la shell bash para crear o modificar una variable de entorno y luego todos los comandos iniciados por la shell heredarán esa variable. ¿Cómo creamos variables de entorno dentro de la shell bash? Primero, una variable de shell se crea y luego la variable de shell es "promovida" a una variable de entorno mediante el comando export, (la variable será luego exportada a cualquier proceso hijo futuro). Considere el siguiente ejemplo: [prince@station prince]$ A=apple [prince@station prince]$ B=banana [prince@station prince]$ echo a:$A b:$B a:apple b:banana [prince@station prince]$ export A [prince@station prince]$ bash [prince@station prince]$ ps PID TTY TIME CMD 2251 pts/5 00:00:00 bash 2316 pts/5 00:00:00 bash 2342 pts/5 00:00:00 ps [prince@station prince]$ echo a:$A b:$B a:apple b: [prince@station prince]$ exit exit [prince@station prince]$ echo a:$A b:$B a:apple b:banana [prince@station prince]$ unset A B El usuario prince ha creado dos variables de shell, A y B. La variable A se promueve a una variable de entorno con el comando export. El usuario prince inicia una subshell bash. Al ejecutar el comando ps, prince confirma que hay otras shells ejecutándose: el padre y el hijo (su shell actual). Dado que la variable A pasa a ser una variable de entorno, ésta fue heredada por la shell hija del padre. Por el contrario, la shell hija no sabe nada de la variable de shell padreB. Cuando prince sale de la shell hija, vuelve a la shell padre, donde la variable B está aún definida. Por último, prince desenlaza tanto la variable de entornoA como la shell de entorno B con el mismo comando unset. Las variables de entorno suelen utilizarse para configurar comandos con información acerca de configuraciones locales o en otras palabras, la información acerca del entorno local. A manera de ejemplo, muchos comandos buscarán una variable de entorno
  • 22. 22 La shell bash llamada LANG para determinar el lenguaje del usuario y modificar su salida como corresponde. [prince@station prince]$ echo $LANG en_US.UTF-8 [prince@station prince]$ date Fri Aug 1 11:54:24 EDT 2002 [prince@station prince]$ LANG=de_DE [prince@station prince]$ date Fre Aug 1 11:54:53 EDT 2002 [prince@station prince]$ LANG=es_ES [prince@station prince]$ date vie ago 1 11:55:09 EDT 2002 Al establecer la variable de entorno LANG para de_DE, la abreviatura habitual para el día "viernes" en alemán entonces se convierte en la abreviación alemana por regla. Al establecer LANG como es_ES, los efectos son incluso más obvios, puesto que las abreviaturas de los días y meses han cambiado al español (como también las convenciones de las mayúsculas). Un punto importante que merece reformularse. El comando date no cambió la conducta porque el comando bash tenía una variable de entorno denominada LANG (directamente). El proceso al ejecutar el comando date modificó su salida porque tenía su propia variable de entorno llamada LANG. Esto simplemente sucedió para heredar esta variable de la shell bash. Todos los procesos tienen variables de entorno, no sólo shells. ¿Por qué prince no tuvo que exportar explícitamente la variable LANG? La variable ya es una variable de entorno configurada por los scripts de arranque. Una vez que una variable es una variable de entorno, se puede modificar ( y suprimir) mediante la misma sintaxis de las variables de shell. A menudo, los usuarios utilizan una sintaxis más corta para crear y exportar una variable de entorno: [prince@station prince]$ export EDITOR=nano Con este sólo comando, prince ha creado, asignado y exportado la variable EDITOR. Listado de variables Examinar variables con set y env La shell bash provee dos comandos para listar variables definidas. El comando set, sin argumentos, lista las variables de shell y las variables de entorno asociadas con la shell, mientras que el comando env, otra vez sin argumentos, lista sólo variables que han sido exportadas al entorno. [prince@station prince]$ set BASH=/bin/bash
  • 23. 23 La shell bash BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release" [5]="i386-redhatlinux-gnu") BASH_VERSION='2.05b.0(1)-release' COLORS=/etc/DIR_COLORS.xterm COLUMNS=80 ... [prince@station prince]$ env HOSTNAME=localhost SHELL=/bin/bash TERM=xterm HISTSIZE=1000 USER=prince MAIL=/var/spool/mail/prince ... Variables de entorno más utilizadas El siguiente cuadro lista algunas variables de entorno que con frecuencia se utilizan para personalizar un entorno de usuario. Table 1. Variables de entorno más utilizadas Variable TERM Uso Especifica la configuración de bajo nivel de la terminal del usuario. La variable es más relevante al utilizar una consola de línea serial ("terminal tonta") para acceder al sistema. PATH Especifica los directorios para buscar archivos ejecutables en ellos. DISPLAY Especifica qué clientes del servidor X deberían usar el entorno gráfico. LANG Especifica el lenguaje preferido para los programas internacionalizados. EDITOR Muchos programas dependen de un editor externo para la entrada de parte del usuario. A menudo, el editor por defecto es vi. Si la variable de entorno EDITOR está establecida, el editor especificado se utilizará en su lugar. PRINTER La mayoría de los comandos que envían o administran trabajos de impresión examinarán esta variable de entorno para determinar la impresora predeterminada. Ejemplos Uso de variables para hacer referencia a las palabras más utilizadas El usuario prince desea mantener al día los aspectos relacionandos con el software de Open Source y suele utilizar los enlaces de texto del navegador web links para visitar http://www.redhat.com/opensourcenow/key_issues.html. En lugar de teclear de modo repetitivo la URL, prince modifica su archivo ~/.bashrc, para que la URL sea almacenada en la variable OSNISSUES. Ahora prince puede referirse a la página web de un modo más fácil.
  • 24. 24 La shell bash [prince@station prince]$ vim .bashrc [prince@station prince]$ cat .bashrc # .bashrc # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi OSNISSUES=http://www.redhat.com/opensourcenow/key_issues.html [prince@station prince]$ bash [prince@station prince]$ links $OSNISSUES Mediante http_proxy para definir un servidor Proxy HTTP Dado que prince está utilizando un computador sin conexión directa al internet, debe configurar su navegador de red para usar el servidor proxy encontrado en la dirección IP 10.1.1.1 y en el puerto 8080. Mientras trata de entender cómo establecer un servidor proxy para el navegador de texto links, se encuentra con lo siguiente en la página de manual links(1). PROTOCOL_proxy that can act Links supports the use of proxy servers as firewall gateways and caching servers. They are preferable servers to the older gateway (see WWW_access_GATEWAY, below). Each protocol used by Links, (http, ftp, gopher, etc), can be mapped separately by setting environment variables of the form PROTOCOL_proxy (literally: HTTP_proxy, FTP_proxy, HTTPS_proxy, etc), to "http://some.server.dom:port/". Con el fin de establecer el servidor proxy, agrega la siguiente línea a su archivo ~/.bashrc. HTTP_proxy=http://10.1.1.1:80 Prince inicia una nueva shell (para que el archivo .bashrc sea leído) y trata de tener acceso a la página web de Open Source. [prince@station prince]$ links http://www.redhat.com/opensourcenow/key_issues.html Looking up www.redhat.com www.redhat.com Unable to locate remote host www.redhat.com Alert!: Unable to connect to remote host.
  • 25. 25 La shell bash links: Can't access startfile http://www.redhat.com/opensourcenow/key_issues.html El navegador de enlaces aparentemente no está tratando de usar el servidor proxy. Cuando prince revisa sus pasos, se da cuenta que aunque configuró la variable http_proxy, olvidó exportar la variable. Dado que la variable es una variable de shell establecida y no una variable de entorno, no es heredada por el proceso links. Prince edita la línea que agregó a su archivo .bashrc, agregándole la palabra exportar: [prince@station prince]$ cat .bashrc # .bashrc # User specific aliases and functions # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi export HTTP_proxy=http://10.1.1.1:80 De nuevo inicia una nueva shell (para que lea el archivo .bashrc otra vez) y ensaya una vez más. [prince@station prince]$ links http://www.redhat.com/opensourcenow/key_issues.html Dado que la variable http_proxy ahora es exportada como una variable de entorno, es heredada por el proceso links, y links usa con éxito el servidor de proxy para contactar el sitio. Puesto que prince incluyó la línea en su archivo ~/.bashrc, la variable de entorno se configurará automáticamente cada vez que inicie una nueva shell, y prince no necesita preocuparse por esto. Agregar un directorio a su PATH Cuando la shell bash examina una línea de comandos, asume que la primera palabra es el nombre del programa que se va a ejecutar. Luego debe ubicar el archivo que contiene el programa en el sistema de archivos. Dado que la búsqueda de un archivo ejecutable, por ejemplo, ls en todo un sistema de archivos, tardaría mucho, la shell busca en la variable de entorno PATH para obtener instrucciones. La variable de entorno PATH contiene una lista de directorios en los cuales deberían buscar los archivos ejecutables, separados por una coma: [prince@station prince]$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/home/prince/ bin
  • 26. 26 La shell bash Considere ejecutar el comando xclock, el cual comienza por un reloj en el entorno gráfico X. Por medio de la variable PATH, bash primero busca el archivo /bin/xclock, y al no encontrarlo, busca entonces /usr/bin/xclock. El proceso continua hasta encontrar el archivo ejecutable /usr/bin/X11/xclock. No todos los archivos ejecutables en el sistema residen en directorios que están en la lista por su variable de entorno PATH. Se dice que algunos programas viven "fuera de su ruta". Sin embargo, el hecho que un programa viva fuera de su ruta, no significa que no pueda ejecutarse. Significa que usted debe especificar el comando mediante una referencia absoluta. A manera de ejemplo, el comando lsof lista los archivos actualmente abiertos en el sistema, (el nombre se deriva del inglés LiSt Open Files.) Dado que este comando lo suelen utilizar administradores de sistemas, y no usuarios "normales", el comando vive en el directorio /usr/sbin, el cual se adhiere "fuera del" PATH por defecto en Red Hat Enterprise Linux. El usuario prince desearía usar el comando para listar todos los archivos actualmente abiertos que el proceso init está utilizando. [prince@station prince]$ -rwxr-xr-x 1 root [prince@station prince]$ -bash: lsof: command not ls -l /usr/sbin/lsof root 95640 Jan 24 lsof -c init found 2003 /usr/sbin/lsof Al examinar su PATH, el directorio /usr/sbin no está listado, así que prince trata de ejecutar el comando como una referencia absoluta. [prince@station prince]$ /usr/sbin/lsof -c COMMAND PID USER FD TYPE DEVICE SIZE init 1 root mem REG 3,3 27036 init 1 root mem REG 3,3 104560 init 1 root mem REG 3,3 1536292 2.3.2.so init NODE 245377 244833 476416 NAME /sbin/init /lib/ld-2.3.2.so /lib/tls/libc- Dado que él preferiría poder ejecutar el comando directamente, prince desearía agregar el directorio /usr/sbin a su ruta. Utiliza un truco estándar de Linux (y Unix) para agregar el directorio a su ruta. [prince@station prince]$ PATH=$PATH:/usr/sbin El comando puede ser pensado como si se dijera "establezca la variable PATH"sea cualquiera que sea actualmente, pero luego agregue :/usr/sbin. Tras examinarlo, la variable PATH ha agregado el directorio /usr/sbin y prince ahora puede listar los archivos fácilmente. [prince@station prince]$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/home/prince/ bin:/usr/sbin [prince@station prince]$ lsof -c init COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root mem REG 3,3 27036 245377 /sbin/init
  • 27. 27 La shell bash init init 2.3.2.so 1 root mem 1 root mem REG REG 3,3 104560 244833 /lib/ld-2.3.2.so 3,3 1536292 476416 /lib/tls/libc- Ejercicios en línea Lab Exercise Objetivo: Establecer y apuntar correctamente varias variables de shell y de entorno. Estimated Time: 30 mins. Especificaciones Estas especificaciones deben aplicarse a las shells recién iniciadas. Edite el script de arranque de bash .bashrc (que se encuentra al comienzo de su directorio de inicio) para incluir los comandos apropiados. 1. Su shell debe incluir el directorio /usr/sbin en su ruta de búsqueda de archivos ejecutables. 2. Tras el arranque, su shell debería crear la variable de entorno PRINTER que apunte a la palabra sales. 3. Sólo por gusto, tras el arranque, haga que su shell establezca la variable HISTSIZE en su proceso actual de shell, (¿qué efecto tendrá esto en su historial de comandos de shell?) 4. Tras el arranque, su shell debería crear la variable de shellCLICHE, la cual debería apuntar a la frase en inglés that is how the cookie crumbles. Asegúrese que la variable no se convierta en una variable de entorno. 5. Tras el arranque, su shell debe redirigir la salida del comando date al archivo en su directorio de inicio titulado ppid_is_my_parent, en donde ppid es remplazado por su id del proceso padre de shell (almacenado en la variable de shell PPID). Si ha configurado su archivo de shell .bashrc correctamente, debería poder reproducir una salida similar a la siguiente. [student@station student]$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/sbin:/ho me/student/bin [student@station student]$ echo $PRINTER sales [student@station student]$ ps PID TTY TIME CMD 3914 pts/3 00:00:00 bash 3948 pts/3 00:00:00 ps [student@station student]$ echo $HISTSIZE 3914 [student@station student]$ echo $CLICHE that is how the cookie crumbles
  • 28. 28 La shell bash [student@station student]$ echo $PPID 4293 [student@station student]$ ls 4293_is_my_parent Deliverables A title Question 1 Un archivo de arranque bash.bashrc configurado correctamente, para que las shells recién creadas bash tengan la siguiente configuración. 1. El directorio /usr/sbin está incluído en la ruta de búsqueda de la shell. 2. La variable de entorno PRINTER apunta a sales. 3. La variable de entorno HISTSIZE apunta al id (PID) del proceso actual de la shell. 4. La variable de shell CLICHE (no es una variable de entorno) apunta a la frase en inglés that is how the cookie crumbles. 5. Tras el arranque, la salida del comando date es redirigida al archivo titulado ppid_is_my_parent en su directorio de inicio, donde ppid es remplazado por el id del proceso padre de la shell. Limpieza Después de que su ejercicio haya sido calificado, probablemente querrá suprimir los cambios hechos en el archivo .bashrc, (en caso contrario, podría terminar con un amplio historial, y demasiados archivos molestos soso_is_my_parent.) Capítulo 4 Expansión de la línea de comandos Conceptos clave • • • • • La shell bash expande ciertos metacaracteres de línea de comandos antes de interpretar el comando. La expansión con la tilde amplía los símbolos que comienzan por una tilde (~) a los directorios de inicio de usuarios. La expansión de llaves amplía los símbolos con corchetes ({}) en palabras múltiples, cada una contiene una sola palabra a partir de la lista especificada. La sustitución de comandos expande el texto delimitado por comillas invertidas (``) o "dólar paréntesis" ($()) en la salida producida por el comando encerrado. Las comillas dobles ("..." ), las comillas sencillas ('...') y el caracter de barra invertida pueden usarse para evitar que la shell expanda los caracteres.
  • 29. 29 La shell bash Expansiones de línea de comandos Generalidades Antes de ejecutar un comando, la shell bash ejecuta varias expansiones en la línea de comandos. Varios tipos de expansiones de bash, tales como la expansón del nombre de ruta (comodín) y la expansión de variables ya se han descrito. El siguiente cuadro lista los tipos de expansiones bash con una descripción de cada una a continuación. Table 1. Expansiones de línea de comandos en la shell bash Expansión Historial Sintaxis ! Se expande hasta Una línea de comandos anterior Llaves {} Texto especificado Tilde ~username Directorio de inicio de un usuario Variable $, ${...} Shell y variables de entorno Aritmética $((...)) Cálculo numérico Sustitución de comandos `...`, $(...) Salida de la ejecución del comando en una subshell Nombre de ruta *, ?, [...], [^...] Nombres de archivos coincidentes en el sistema de archivos Expansión del historial La expansión del historial, la cual se invoca con un signo de exclamación, se describió de modo extensivo en una lección anterior. Aquí se incluye debido al contexto. Expansión de llaves La expansión de llaves expande una sola palabra en palabras múltiples, sustituyendo uno de los elementos en "llave" para cada palabra. Por ejemplo, la expresión {c,b,r}at se expandiría en tres palabrascat bat rat. La expansión de llaves se utiliza para referirse (o crear) archivos que tienen prefijos, postfijos o componentes de ruta comunes, (recuerde que varios ejercicios de laboratorio han utilizado expansión de llaves para crear rápidamente un gran número de directorios o archivos y luego subdirectorios dentro de ellos). [prince@station prince]$ mkdir chap{01,02,03,04} El usuario prince ahora tiene los siguientes cuatro directorios: . |-- chap01/ |-- chap02/ |-- chap03/
  • 30. 30 La shell bash `-- chap04/ 4 directories, 0 files [prince@station prince]$ mkdir chap{01,02,03,04}/{html,text} Ahora se han agregado los siguientes directorios. . |-| | |-| | |-| | `-- chap01/ |-- html/ `-- text/ chap02/ |-- html/ `-- text/ chap03/ |-- html/ `-- text/ chap04/ |-- html/ `-- text/ 12 directories, 0 files En el primer comando mkdir, la palabra entre corchetes se expande a cuatro directorios chap01, chap02, chap03, y chap04. En el segundo comando mkdir, la palabra con doble corchete se expande a ocho directorios chap01/html, chap01/text, chap02/html y así sucesivamente. A diferencia de los archivos/comodines, las palabras que resultan de la expansión de llaves no coinciden con los archivos en el sistema de archivos (los archivos no tienen que existir). De hecho, las palabras expandidas no tienen que ser nombres de archivos, aunque en la práctica suelen serlos. Expansión de tilde Quizás este es el concepto más sencillo de expansión, la expansión de tilde, el cual expande un ~nombredeusuario para el usuario del directorio de inicio del nombredeusuario, como se listó en el archivo/etc/passwd (o la base de datos apropiada del usuario). A continuación, prince utiliza la expansión tilde para referirse a su directorio propio y a los directorios de elvis, y luego un subdirectorio del directorio de inicio de elvis. [prince@station drwx-----x 15 drwx-----x 9 [prince@station total 4 drwxrwxr-x 2 prince]$ elvis prince prince]$ ls -ld ~ ~elvis elvis 4096 Jul 21 17:41 /home/elvis prince 4096 Aug 4 06:58 /home/prince ls -l ~elvis/pub elvis music 4096 Jul 13 05:46 music
  • 31. 31 La shell bash A menudo en este curso y en otros textos, la tilde se utiliza para implicar que un archivo debería existir en el directorio de inicio del usuario, tal como el archivo ~/.bash_history. Ahora podemos ver la razón de esta convención. Expansión de variables La expansión de variables se trató de modo extenso en la lección anterior. Reformulando, la shell bash expandirá (desreferenciará) expresiones de la forma $VARNAME o ${VARNAME} al valor de la shell o variable de entornoVARNAME. Expansión aritmética La shell bash suele considerarse un entorno deficiente para cálculos numéricos y los operadores aritméticos tales como +, -, *, y / en la línea de comando no tienen el significado matemático habitual. Sin embargo, la shell bash trata de manera especial texto delimitado con una sintaxis $((...)). Primero, las variables se tratan como enteros numéricos cuando resulte apropiado, y segundo, los operadores matemáticos estándar como por ejemplo +, -, *, y / se tratan como tal. La shell bash "expandirá" toda la expresión y la remplazará por el resultado numérico. Los operadores aritméticos son los mismos del lenguaje de programación C y están totalmente documentados en la página de manual bash(1) bajo "EVALUACIÓN ARITMÉTICA". En el siguiente ejemplo, prince utilizará una expansión aritmética para calcular el área de un rectángulo. [prince@station prince]$ WIDTH=16 [prince@station prince]$ HEIGHT=82 [prince@station prince]$ echo $(( $WIDTH * $HEIGHT)) 1312 Sin embargo, las limitaciones de cálculos numéricos se descubren rápidamente cuando prince trata de volver a calcular el área mediante un número de punto flotante. [prince@station prince]$ WIDTH=16.8 [prince@station prince]$ echo $(( $WIDTH * $HEIGHT)) -bash: 16.8 * 82: syntax error in expression (error token is ".8 * 82") La shell bash sólo soporta enteros aritméticos. Sustitución de comandos Quizás de las expansiones más complejas y útiles, la sustitución de comandos permite a los usuarios ejecutar comandos arbitrarios en la subshell e incorporar los resultados dentro de la línea de comandos. La sintaxis de la"vieja escuela" para la sustitución de comandos es encerrar el comando entre "acentos graves" (la comilla simple inclinada hacia la izquierda que se encuentra en la misma tecla de ~, cerca de 1 en la mayoría de los teclados), y el comando de sustitución suele denominarse "sustitución de acentos
  • 32. 32 La shell bash graves". La sintaxis más moderna soportada por la shell bash es similar a la expansión aritmética, pero con solo un par de paréntesis: $(subcomando) Como ejemplo de una sustitución de comandos, prince desearía crear un directorio que contenga la fecha en su nombre. Después de examinar la página de manual date(1), crea una cadena de formato para generar la fecha en un formato compacto. [prince@station prince]$ date +%d%b%Y 04May2003 Ahora, ejecuta el comando mkdir mediante la sustitución de comandos. [prince@station prince]$ mkdir reports.$(date +%d%b%Y) [prince@station prince]$ ls reports.04May2003 O pudo haber combinado las ventajas de la sustitución de comandos y la sustitución del historial como se muestra a continuación. [prince@station prince]$ mkdir reports.$(!da) mkdir reports.$(date +%d%b%Y) [prince@station prince]$ ls reports.04May2003 La shell bash implementa la sustitución de comandos al generar una nueva subshell, ejecutar el comando, registrar la salida y salir de la subshell. El texto se utiliza para invocar la sustitución de comandos luego es remplazado por la salida registrada desde el comando. Expansión de nombre de ruta La expansión de nombre de ruta o "comodín de archivo", se describió en el cuaderno anterior, pero no se introdujo como una expansión de shell. Ahora podemos ver que el nombre de ruta es uno de los tipos de expansiones implementados por la shell bash. Para repasar, la sintaxis de la expansión del nombre de ruta vea la siguiente tabla. Table 1. Expansión del nombre de ruta bash Caracter Coinciden * 0 ó más caracteres ? exactamente un caracter [...] exactamente uno de los caracteres incluídos [^...] exactamente uno de los caracteres excluídos Comillas y caracteres de escape
  • 33. 33 La shell bash La shell bash usa varios caracteres de puntuación que se encuentran en el teclado para ejecutar diferentes tipos de expansiones, redirecciones y otra clase de actos de expertos. Aunque es eficaz, hay situaciones en que los usuarios desean utilizar uno de estos caracteres sin la invocación de ningún tipo de conducta especial. Parafraseando a Sigmund Freud, "A veces un signo dólar es sólamente un signo de dolar." La shell bash proporciona tres mecanismos para evitar que los caracteres sean interpretados por la shell, escapando, utilizando comillas dobles o sencillas. Table 1. Uso de comillas y escape de la shell bash Efecto Sintaxis Impide que el siguiente caracter sea interpretado por la shell. "..." Impide que los caracteres incluídos sean interpretados por la shell, exceptuando los caracteres $, !, y ` (acento grave). '...' Impide que todos los caracteres incluídos sean interpretados por la shell. Considere los siguientes ejemplos, donde prince está tratando de imprimir en pantalla. En el primer caso, prince define la variable CAR, y trata de imprimir la línea sin comillas. [prince@station prince]$ CAR=corvette [prince@station prince]$ echo <pre>little red $CAR</pre> -bash: syntax error near unexpected token `newline' Sin comillas, bash interpretó los caracteres > y < como solicitudes para redirigir la salida (y entrada) del comando. La shell se confundió cuando se le pidió redirigir la salida dos veces. El usuario prince, trata de nuevo, esta vez utilizando comillas dobles. [prince@station prince]$ echo "<pre>little red $CAR</pre>" <pre>little red corvette</pre> En este caso, las comillas dobles protegieron los caracteres < y >. Sin embargo, el signo de dólar, todavía se interpreta como marcador para una variable. El usuario prince intenta de nuevo con comillas sencillas. [prince@station prince]$ echo '<pre>little red $CAR</pre>' <pre>little red $CAR</pre> En este caso, todos los caracteres de puntuación fueron protegidos de la interpretación de la shell. Como una alternativa, los caracteres pueden escaparse individualmente con una barra invertida precedente. [prince@station <pre>little red [prince@station >pre<little red prince]$ echo <pre>little red $CAR</pre> corvette</pre> prince]$ echo <pre>little red $CAR</pre> $CAR</pre>
  • 34. 34 La shell bash Una nota sobre las comillas Como hemos visto, bash hace uso de una variedad de signos de puntuación relacionados con comillas, asignando a cada uno un propósito diferente. Los tres estilos de comillas se ilustran con el comando echo de abajo. Con el fin de reforzar las diferencias, los tres estilos de comillas se describen a continuación. [prince@station prince]$ FOOD=guacamole [prince@station prince]$ echo "wow! `whoami` sells $FOOD" 'for $!' wow! prince sells guacamole for $! Comillas dobles: "..." Las comillas dobles se utilizan en situaciones donde usted desearía tratar la mayoría de la puntuación literalmente o combinar palabras en un sólo símbolo, pero aún puede hacer uso de variables, sustitución de comandos y sustitución de historial. Comillas sencillas inclinadas a la derecha (apóstrofes): '...' Las comillas sencillas son las más poderosas y se utilizan en situaciones similares a las comillas dobles cuando quiere que toda la puntuación, incluyendo las variables y la sustitución de comandos, se traten literalmente. Comillas sencillas inclinadas hacia la izquierda (acentos graves): `...` Los acentos graves son básicamente diferentes a las comillas simples o dobles, no son para citar. Estos acentos se utilizan para invocar la sustitución de comandos en el texto incluido. Sutilezas de la expansión de línea de comandos Hemos visto que bash se aplica a un gran número de expansiones de línea de comandos antes de que un comando se ejecute. La frase incluye una sutileza que no siempre es apreciada y puede algunas veces llevar a confusiones. Las expansiones de shell se presentan antes de que el comando se ejecute. A veces, algunos los comandos esperan argumentos que contienen caracteres especiales para la shell bash. Un ejemplo es el comando find. Si no se tiene cuidado al utilizar comillas o escapar los caracteres especiales, bash podría "expandirlos" antes de que el comando los vea. El siguiente ejemplo del comando find en acción podría ayudar. Al iniciar desde un directorio vacío, prince ejecuta find para buscar todos los archivos terminados en .conf en el directorio /etc. [prince@station prince]$ find /etc -name *.conf find: /etc/sysconfig/pgsql: Permission denied /etc/sysconfig/networking/profiles/default/resolv.conf /etc/sysconfig/networking/profiles/netup/resolv.conf find: /etc/default: Permission denied /etc/X11/gdm/factory-gdm.conf
  • 35. 35 La shell bash /etc/X11/gdm/gdm.conf /etc/modprobe.conf ... Pasando por alto algunas quejas acerca de los directorios inaccesibles, el comando funciona. Luego, prince crea los archivos a.conf y b.conf en el directorio local e intenta de nuevo. [prince@station prince]$ touch a.conf b.conf [prince@station prince]$ ls a.conf b.conf [prince@station prince]$ find /etc -name *.conf find: paths must precede expression Usage: find [path...] [expression] ¿Por qué el comando que funcionó hace apenas unos segundos no funciona ahora? La respuesta, como podría esperarse, tiene que ver con la expansión de línea de comandos. Primero, veamos el segundo caso. La shell bash encontró el siguiente comando. find /etc -name *.conf ¿Qué hace primero bash? Aplica la expansión de línea de comandos. Después de examinar el directorio local y hallar los archivos a.conf y b.conf, la shell remplaza el comodín *.conf con los nombres de archivo coincidentes, a.conf b.conf. Esta es una expansión de nombre de ruta bastante antigua. Después de la expansión, el comando se ve de esta manera. find /etc -name a.conf b.conf Ahora bash ejecuta el comando, el cual genera un mensaje de error (porque la opción name no pudo manejar dos argumentos). Volviendo al primer comando, ¿por qué funcionó? Al implementar la expansión del nombre de ruta, la shell bash intenta ayudar a la gente. Si un comodín "falta " (por ejemplo, ningún archivo coincide con la expresión especificada), bash conserva el comodín. En el primer caso, como ninguno de los archivos coincidió con *.conf, bash pasó el argumento al comando find como está escrito. [1] ¿Cuál es la forma correcta de manejar la situación? Usar comillas o escapar los caracteres especiales, como se muestra a continuación: [prince@station prince]$ find /etc -name "*.conf" find: /etc/sysconfig/pgsql: Permission denied find: /etc/default: Permission denied /etc/sysconfig/networking/profiles/default/resolv.conf /etc/sysconfig/networking/profiles/netup/resolv.conf /etc/X11/gdm/factory-gdm.conf /etc/X11/gdm/gdm.conf /etc/modprobe.conf ...
  • 36. 36 La shell bash Debido a que se ha utilizado el * , la shell bash no intentará realizar una expansión de nombre de ruta y el comando funciona como se desea. La lección es: si está pasando un caracter especial dentro de un comando, usted debería proteger el caracter con comillas (o un escape de barra invertida). Ejemplos Uso de expansión de llaves El usuario prince está configurando un directorio llamadoogg en el que va a almacenar archivos de música que ha "quemado" (copiado) de sus discos favoritos. Con el fin de organizar las cosas, le gustaría crear directorios basados en estilos diferentes de música y en cada uno de los subdirectorios crear un archivo llamado playlist. En la siguiente transcripción, prince usa una expansión de llave para agilizar su trabajo. [prince@station prince]$ mkdir ogg [prince@station prince]$ mkdir ogg/{blues,folk,rap,pop} [prince@station prince]$ touch ogg/{blues,folk,rap,pop}/playlist En este punto, prince ha creado la siguiente estructura de directorio. ogg/ |-- blues | `-- playlist |-- folk | `-- playlist |-- pop | `-- playlist `-- rap `-- playlist 4 directories, 4 files ¿Pudo prince haber utilizado el comodín de archivo (expansión de nombre de ruta) en su lugar? Al utilizar el comando mkdir, el comodín de archivo habría sido inútil porque los directorios blues, folk, etc.., no existían. ¿Qué sucedería si prince hubiera utilizado el comodín de archivo para el comando touch? [prince@station prince]$ touch ogg/*/playlist touch: creating `ogg/*/playlist': No such file or directory Los directorios blues, folk, etc., existeron, pero ninguno de los archivos playlist existia, por lo tanto el comodiín se perdió. Para situaciones en que el archivo podría o no existir, la expansión de llaves tiende a funcionar mejor que el comodín. Más acerca de la terminación con el tabulador Hemos visto que la shell bash graba las pulsaciones al completar nombres de comandos o nombres de archivos cuando se pulsa la tecla TAB. La shell bash completará nombres de usuario y variables, cuando las palabras comienzan por los caracteres ~ o $,
  • 37. 37 La shell bash respectivamente. Por ejemplo, si un usuario escribe ~el<TAB>, bash podría completar el símbolo ~elvis. De la misma manera, $PA<TAB> podría completarse $PATH. De forma similar a la expansión del comando y nombre de archivo, si los caracteres iniciales tecleados hasta el momento no especifican únicamente una variable (o nombre de usuario), bash emite un pitido. Al pulsar dos veces el TAB se listarán las posibles terminaciones. Poner entre comillas los nombres de archivos raros En un cuaderno anterior, mencionamos que los nombres de archivo en Linux (y Unix) podrían estar compuestos por cualquier caracter a excepción de uno (¿Recuerda cuál?[1]) En el mismo cuaderno, se les dijo a los estudiantes que aunque se podían utilizar caracteres especiales, era mejor evitarlos. Ahora estamos en una buena posición para ver el porqué. Suponga que prince quiere crear un archivo único llamado Make $$$ *Fast* !!. [prince@station prince]$ touch Make $$$ *Fast* !! touch Make $$$ *Fast* l [prince@station prince]$ ls 13986$ *Fast* l Make El comando touch accede, creando los archivos que bash le pide hacer. Primero, como los símbolos están separados por espacios, bash los trata como cuatro palabras separadas. Luego la shell bash aplica sus distintas expansiones a las palabras. 1. El archivo Make se crea fácilmente. 2. La shell bash aplica la sustitución de variables a $$$, resultando en 13986$. (¿De dónde sale el número 13986?[2]) 3. El símbolo *fast* sobrevive con el preservado del *, pero ese no tenía que ser el caso. 4. Por último, !! se expande a l desde el historial de comandos del usuario, el cual aparentemente (y un poco extraño) fue el anterior comando ejecutado. Una vez se han aplicado las extensiones, la shell bash invoca touch con cuatro argumentos, para que touch obedientemente cree cuatro archivos. ¿De qué manera persuadimos a bash para que cree un archivo con nuestro rito proporcionado por Linux de incluir espacios y puntuación en el nombre de archivo? Obviamente con comillas. [prince@station prince]$ touch 'Make $$$ *Fast* !!' [prince@station prince]$ ls 13986$ *Fast* l Make Make $$$ *Fast* !! Con sólo ls, es difícil distinguir entre múltiples archivos y un archivo único con espacios en el nombre. Un ls -l ayuda a aclarar la situación. [prince@station prince]$ ls -l total 0
  • 38. 38 La shell bash -rw-rw-r--rw-rw-r--rw-rw-r--rw-rw-r--rw-rw-r-*Fast* !! 1 1 1 1 1 prince prince prince prince prince prince prince prince prince prince 0 0 0 0 0 Aug Aug Aug Aug Aug 31 31 31 31 31 06:19 06:19 06:19 06:19 06:40 13986$ *Fast* l Make Make $$$ Observe que las comillas sirven en realidad para dos propósitos. 1. Las comillas inhiben la interpretación de los signos de puntuación como lo solicitan las expansiones de shell. 2. Las comillas impiden la división de palabras, la cual es la forma como la shell bash compone argumentos para los programas que ejecuta. Por ejemplo, el comando touch one two three haría que bash ejecute el comandotouch con tres argumentos, one, two, y three. Por el contrario, el comando touch "one two three" haría que bash pase el único argumento del comando touch a one two three (aunque uno con espacios). Ejercicios en línea Lab Exercise Objetivo: Usar varias sustituciones de shell bash de modo efectivo. Tiempo estimado: 15 minutos. Especificaciones 1. Configure su archivo ~/.bashrc para que, tras el arranque, la variable LINUX_VERS contenga toda la primera línea del archivo /var/log/dmesg, (el archivo /var/log/dmesg se regenera cada vez que se arranca la máquina, por lo que deberá establecer la variable de modo dinámico. Recuerde que el comando head -1 mostrará la primera línea del archivo). 2. En su directorio de inicio, cree archivos con los sigu¡entes nombres de archivo, (el contenido de los archivos es irrelevante). a. archivo sin título b. **'s y ||'s c. >> README!! << 3. En su directorio de inicio, cree un subdirectorio denominado shirts. Dentro del subdirectorio, cree 108 archivos de la forma estilo.tamaño.color.ext, donde cada archivo contenga una combinación de valores a partir del cuadro siguiente. Estilo tee, crew, turtleneck Tamaño XXL, XL, L, M, S, XS Color red, yellow, blue Extensión info, inv
  • 39. 39 La shell bash 4. Por ejemplo, el directorio debería contener archivos titulados tee.XXL.red.info, tee.XXL.red.inv, tee.XL.red.info, tee.XL.red.inv y así sucesivamente. Deliverables A title Question 1 1. Tras el arranque, la variable LINUX_VERS debe establecerse para que contenga la primera línea del archivo /var/log/dmesg. 2. Los archivos a continuación deberían existir en el directorio de inicio del usuario. a. archivo sin título b. **'s y ||'s c. >> README!! << 3. Un directorio llamado ~/shirts, el cual contiene exactamente 108 archivos, cada uno de forma estilo.tamaño.color.ext. Cada nombre de archivo contiene una combinación de los valores que aparecen en el cuadro de arriba. Capítulo 5 Personalización de la shell Conceptos clave • • • • • • • La shell bash internamente implementa ciertos comandos sencillos que están muy ligados con la conducta de la shell. Estos se conocen como los comandos incorporados. Los alias de shell crean comandos aparentes que expanden a texto arbitrario. Los alias de shell se establecen y examinan con el comando alias. Los alias de shell se remueven con el comando unalias. El intérprete de comandos de la shell bash se puede personalizar mediante la variable PS1. Las banderas de shell se pueden establecer con el comando set -f y se limpian con set +f. Las opciones de shell se examinan, establecen y se anulan con el comando shopt. Esta lección se centra en las técnicas utilizadas para personalizar la shell bash, como por ejemplo crear comandos alias, personalizar el intérprete de comandos de la shell y establecer las opciones de la shell. La lección comienza con un tema que no es la
  • 40. 40 La shell bash personalización real, pero está relacionada con la conducta de la shell, el tema de los comandos internos. Comandos internos de la shell Al evaluar una línea de comandos, la shell trata la primera palabra como un comando. La shell bash implementa algunos comandos de modo interno, lo que significa que los comandos no existen en el sistema de archivos como un programa cargable, sino que la shell misma los implementa. Estos comandos se conocen como comandos internos de la shell. Estos suelen ser comandos sencillos relacionados con cambios a la shell misma. En un cuaderno anterior, presentamos el comando which, el cual reportará en qué parte del sistema de archivo reside el archivo ejecutable que contiene un comando en particular. A continuación, madonna observa que el comando date es implementado por el programa que se encuentra en el archivo ejecutable /bin/date: [madonna@station madonna]$ which date /bin/date ¿Qué sucede cuando madonna utiliza which para buscar el archivo ejecutable que contiene el programa cd? [madonna@station madonna]$ which cd /usr/bin/which: no cd in (/usr/local/j2sdk1.3.1/bin:/bin:/usr/bin:/usr/local/bin :/usr/bin/X11:/usr/X11R6/bin:/home/madonna/bin) De acuerdo con which, el comando cd no existe como ejecutable en el sistema de archivos. El comando cd es un ejemplo de un comando interno de la shell. Una lista de comandos internos de la shell y su documentación correspondiente se puede ver mediante el comando help, el cual es en sí mismo un comando interno de la shell. [madonna@station madonna]$ help GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu) These shell commands are defined internally. Type `help' to see this list. Type `help name' to find out more about the function `name'. Use `info bash' to find out more about the shell in general. Use `man -k' or `info' to find out more about commands not in this list. ... alias [-p] [name[=value] ... ] bind [-lpvsPVS] [-m keymap] [-f fi builtin [shell-builtin [arg ...]] cd [-L|-P] [dir] compgen [-abcdefgjksuv] [-o option ... bg [job_spec] break [n] case WORD in [PATTERN [| PATTERN]. command [-pVv] command [arg ...] complete [-abcdefgjksuv] [-pr] [-o
  • 41. 41 La shell bash El comando help entrega una versión de la información sobre la shell, menciona un par de sitios donde la documentación de bash puede encontrarse y presenta bota una lista de comandos internos. Observe que la lista contiene el comando cd. El comando help también se puede utilizar para ver documentación detallada acerca de un comando interno específico. [madonna@station madonna]$ help cd cd: cd [-L|-P] [dir] Change the current directory to DIR. The variable $HOME is the default DIR. The variable CDPATH defines the search path for the directory containing DIR. Alternative directory names in CDPATH are separated by a colon (:). A null directory name is the same as the current directory, i.e. `.'. If DIR begins with a slash (/), then CDPATH is not used. If the directory is not found, and the ... Dado que el comando cd está ligado a la conducta de la shell, es decir, cambia el directorio de trabajo de la shell, este es un buen candidato para un comando interno. Varios comandos que ya ha estado utilizando, tales como cd, pwd, y echo, son en realidad internos de la shell. Alias Los alias permiten a los usuarios personalizar los nombres de los comandos o enlazar comandos con las opciones o argumentos más utilizados. Una vez creados, los alias se utilizan como si fueran cualquier otro comando. El comando alias Los alias se crean (y examinan) mediante el comando interno alias. Al crear alias, el comando alias utiliza la siguiente sintaxis. alias NAME=VALOR Este comando crearía un alias denominado NOMBRE, el cual apuntaría al valor VALOR. La sintaxis debería ser reminiscente a la utilizada para asignar variables de shell. En particular, como en la asignación de variable, la asignación de alias no permite espacios en ningún lado del signo de igual. Del mismo modo, dado que la sintaxis sólo espera un símbolo único después del signo igual, las frases que contienen múltiples palabras (separadas por espacios) deben ir entre comillas. En el siguiente ejemplo, madonna establece el alias h como un atajo para el comando head. Dado que el alias apunta a una sola palabra (head), madonna no tiene que preocuparse por citar el valor. Luego utiliza el nuevo alias para examinar varias de las primeras líneas del archivo /etc/services. [madonna@station madonna]$ alias h=head [madonna@station madonna]$ h /etc/services
  • 42. 42 La shell bash # /etc/services: # $Id: 010_text.dbk,v 1.3 2004/01/07 18:41:02 bowe Exp $ # # Network services, Internet style # # Note that it is presently the policy of IANA to assign a single well-known # port number for both TCP and UDP; hence, most entries here have two entries # even if the protocol doesn't support UDP operations. # Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all ports # are included, only the more common ones. En el siguiente ejemplo, madonna advierte que a menudo está listando todos los procesos ejecutándose en la máquina con el comando ps aux. Decide entonces que cada vez que ejecute ps, prefería la salida más completa que ps aux presenta y por lo tanto establece un alias para el comando ps. [madonna@station madonna]$ alias ps="ps aux" [madonna@station madonna]$ ps USER PID %CPU %MEM VSZ RSS TTY STAT START root 1 0.0 0.0 1376 72 ? S Aug30 root 2 0.0 0.0 0 0 ? SW Aug30 [keventd] root 3 0.0 0.0 0 0 ? SW Aug30 root 4 0.0 0.0 0 0 ? SWN Aug30 [ksoftirqd_CPU0] root 9 0.0 0.0 0 0 ? SW Aug30 [bdflush] root 5 0.0 0.0 0 0 ? SW Aug30 [kswapd] ... TIME COMMAND 0:04 init [ 0:00 0:00 [kapmd] 0:00 0:00 0:00 En este caso, puesto que ella quiso que el alias apuntara a una frase de dos palabras (ps y aux), necesitó encerrar la frase entre comillas (para que tras "la división de palabras", la shell trate la frase como una sola palabra). El comando alias también se utiliza para examinar los alias actualmente definidos. Si madonna quisiera repasar los alias que estableció podría sencillamente ejecutar el comando alias (sin argumentos). [madonna@station madonna]$ alias alias h='head' alias l.='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias ls='ls --color=tty' alias ps='ps aux' alias vi='vim' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
  • 43. 43 La shell bash El comando alias lista los alias establecidos por madonna (h y ps), como también otros alias establecidos por los scripts de arranque bash de madonna (y son parte de la configuración predeterminada de Red Hat Enterprise Linux). Si se dan argumentos (sin el signo de igual), el comando alias mostrará el alias actual para el argumento, si existe alguno: [madonna@station madonna]$ alias ps h foo alias ps='ps aux' alias h='head' -bash: alias: foo: not found El comando unalias Los alias se pueden suprimir con el comando interno de la shell unalias. Para suprimir un alias, pase el nombre de alias como un argumento al comando unalias. A continuación madonna suprime el alias que creó anteriormente para ps. [madonna@station madonna]$ unalias ps [madonna@station madonna]$ alias ps -bash: alias: ps: not found Evaluación de alias ¿Cuándo busca alias la shell de bash ? A diferencia de las variables, no hay signos de puntuación asociados con ninguna clase de "expansión de alias". En su lugar, la shell de bash busca alias en donde se espera un comando (es decir, como la primera palabra en la línea de comando). Si la primera palabra es reconocida como un alias , el alias se expande. La excepción es si el alias se expande al comando que tiene el mismo nombre de alias en cuyo caso la shell simplemente ejecuta la expansión y sigue adelante, (de otra manera, los usuarios podrían fácilmente crear alias que pondrían la shell en un bucle infinito). Los usuarios pueden no darse cuenta de que están usando alias en lugar del comando mismo. Un buen ejemplo es la configuración predeterminada de Red Hat Enterprise Linux, la cual alias el comando ls al valor ls --color=tty, (este instruye a ls para proporcionar caracteres de control especiales que dan color a diferentes tipos de archivos, pero solo si el comando está escribiendo en una terminal. Cuando se redirige a un archivo, no se presenta ningún color). Ejecución de comandos Hemos descrito varios tipos de palabras considerados por la shell bash como "comandos". Para resumir, y proveer un contexto, la siguiente lista resume los pasos que la shell bash realiza al evaluar la primera palabra de la línea de comandos, (el siguiente no es el algoritmo exacto, el cual es más complicado, pero sirve como una aproximación útil).
  • 44. 44 La shell bash 1. Realiza cualquier expansión de la shell. 2. ¿La palabra se define como un alias? Si es así, expanda el alias y vuelva a comenzar (a menos que el alias se expanda a un comando que tenga el mismo nombre del alias en cuyo caso expande el alias y empieza de nuevo, pero no vuelve a expandir alias). 3. ¿La palabra se define como una función de una shell? Si es así, llame la función de la shell en la shell actual, (las funciones de la shell van más allá del alcance de este curso, pero están incuídas aquí para completar la información). 4. ¿La palabra es un comando intermo de la shell? Si es así, ejecute el comando interno. 5. ¿La palabra contiene un /? Si es así, ejecute el archivo si existe y tiene permisos ejecutables. 6. Si la palabra no contiene un /, busque un archivo con un nombre similar en todos los directorios en orden como se definió en el entorno de variable PATH. Si existe un archivo coincidente y tiene permisos ejecutables, ejecute el archivo. Personalizar el intérprete de comandos de bash La shell bash interactiva, mientras que repite su bucle de "escuchar", "evaluar" y "ejecutar", expide un intérprete de comandos cada vez que vuelve a la etapa de "escuchar". El intérprete de comandos se utiliza para contarle al usuario que la evaluación de la etapa anterior ha terminado y que la shell está esperando intrucciones. En la configuración predeterminada de Red Hat Enterprise Linux , el intérprete de comandos también provee más información, incluyendo el nombre de usuario actual, nombre de la máquina y directorio de trabajo. El comando bash en realidad tiene cuatro intérpretes de comandos diferentes los cuales se utilizan en diferentes situaciones. Los dos más vistos son el intérprete de comandos primario, utilizado cada vez que bash está listo para un nuevo comando y el intérprete de comandos secundario utilizado cuando un usuario presiona la tecla INTRO, pero la línea de comandos tiene obviamente una sintaxis inacabada (tal como unas comillas que aún no se han cerrado). A continuación [madonna@station madonna]$ sirve de intérprete de comandos primario, mientras que> sirve de intérprete de comandos secundario. [madonna@station madonna]$ echo "Little Miss Muffet > Sat on a Tuffet" Little Miss Muffet Sat on a Tuffet Personalización del intérprete de comandos de bash con PS1 y PS2 Los usuarios pueden personalizar los intérpretes de comandos de bash mediante las variables de shell PS1 y PS2, las cuales bash usa para componer los dos prompts. El ejemplo anterior implicó que el intérprete de comandos primario es la forma de decir de bash "Estoy esperando", y el intérprete de comandos secundario es la forma de decir de bash "Todavía estoy esperando". Para plantear el punto de una forma obvia, madonna personalizará sus intérpretes de comandos para decir justo eso.
  • 45. 45 La shell bash [madonna@station madonna]$ PS1="I'm waiting ... " I'm waiting ... PS2="I'm still waiting ... " I'm waiting ... echo "Hickory Dickory Dock I'm still waiting ... three mice ran up the clock" Hickory Dickory Dock three mice ran up the clock Estoy esperando ... Inmediatamente tras cambiar el valor de la variable PS1, bash comenzó a utilizar el nuevo valor como su intérprete de comandos primario. A menudo los usuarios desearían que el intérprete de comandos también visualizara información útil. La shell de bash permite a los usuarios insertar secuencias de escape dentro de la definición de PS1, que remplaza con información dinámica cuando se genera el intérprete de comandos. El cuadro a continuación resume algunas de las secuencias más comunes. Para obtener una lista más completa, vea la página de manual bash(1). Table 1. Secuencias de escape comunes utilizadas en intérpretes de comandos bash Secuencia Expansión a Campana audible de la terminal d fecha en formato"día mes" h el nombre del host hasta el primer "." T La hora actual en formato de 12 horas HH:MM:SS u el nombre de usuario del usuario actual W el nombre de la base del directorio de trabajo actual ! El número de historial de este comando $ Si el UID efectivo es 0, un #, de lo contrario un $ nnn el caracter correspondiente al número octal nnn La expansión de parámetros (variables), la expansión aritmética, y la sustitución de comandos se aplican al valor de PS1 cuando el intérprete de comandos es generado también. La secuencia de escape $ puede requerir más explicación. La shell de bash utiliza esta secuencia para reproducir una característica de la shell Bourne originial (/bin/sh). El intérprete de comandos por defecto de la shell Bourne es un dólar ($) para los usuarios estándar y un signo (#) para el usuario root. Con la secuencia de escape $, un valor predeterminado PS1 para todo el sistema puede utilizarse, imitándo esta conducta original. Al personalizar el intérprete de comandos de bash, el intérprete de comandos suele verse más limpio si la variable PS1 está definida con un espacio al final.
  • 46. 46 La shell bash Opciones y banderas de la shell de bash Se utilizan dos comandos internos para configurar la conducta de la shell mediante las opciones de shell. Uno es el comando set, el cual se utiliza para modificar la conducta de shell mediante (por lo general) banderas de una letra, y el otro esshopt, usado para configurar las opciones de la shell. Banderas de la shell: el comando interno set El comando set realiza una labor triple. Cuando se utiliza con la línea de comandos, como suele ser el caso, el comando se utiliza para establecer, o anular las banderas de shell. Observe el cuadro siguiente con las banderas más utilizadas y sus opciones. Cuando se llamado sin argumentos, el comando set visualiza todas las variables de shell y sus valores (como se describió en una lección anterior). El último uso del comando incorporado se utiliza en la escritura de shell y por ahora puede hacerse caso omiso sin ningún problema. Table 1. Banderas de la shell que el comando interno set utiliza. Bandera Efecto -f Inhabilita la expansión de nombres de ruta (comodín) -n Lee comandos pero no los ejecuta (se usa para revisar sintaxis en los scripts). Establece la opción especificada. Algunas de las opciones más comunes incluyen lo siguiente. emacs Emplea líneas de comandos con enlaces de teclas del estilo emacs -o nombredeopción ignoreeof No sale de la shell cuando se lee EOF (CTRL-D) vi Usa enlaces clave de línea de comando del estilo vi -v Imprime comandos como se leen (útil para depurar scripts) -x Imprime comandos despues de aplicadas las expansiones (útil para depurar scripts y examinar expansiones de la shell) -C No le permite a la shell reescribir archivos en redirección. El comando set con la sintaxis normal de las opciones (tal como set -x) habilita la bandera especificada. Para inhabilitar la bandera, remplace el guión (-) por un signo más
  • 47. 47 La shell bash (+) (tal como set +x). La lista de opciones establecidas puede almacenarse en la variable de shell $-. Por ejemplo, a continuación, madonna temporalmente inhabilita el comodín de archivo (habilitando la bandera de shell -f) y luego restaurando el comodín de archivo (inhabilitando el mismo). [madonna@station madonna]$ set -f [madonna@station madonna]$ ls /etc/*.conf ls: /etc/*.conf: No such file or directory [madonna@station madonna]$ set +f [madonna@station madonna]$ ls /etc/*.conf /etc/aep.conf /etc/lftp.conf /etc/pnm2ppa.conf /etc/aeplog.conf /etc/libuser.conf /etc/pwdb.conf /etc/cdrecord.conf /etc/logrotate.conf /etc/resolv.conf /etc/esd.conf /etc/lpd.conf /etc/rndc.conf ... No se preocupe si no entiende aún los efectos de todas las banderas de shell. En su lugar, asegúrese de saber cómo se utiliza el comando set para habilitar o inhabilitar una bandera si es necesario. Si en una lección posterior le dijeran "esta acción puede inhabilitarse al configurar la bandera -H de shell ", usted sabrá cómo hacerlo. Opciones de la shell: el comando interno shopt El comando bash también tiene una segunda serie de variables de configuración, las cuales se conocen como "opciones de shell". Estas se establecen y se anulan mediante el comando shopt donde shopt -s nombreopciónestablece la opción nombreopción, y shopt -u nombreopción anula la opción. El comando shopt nombreopción visualiza el estado actual de la opción, mientras que solo shopt visualiza todas las opciones de la shell. Algunas de las opciones de shell más fáciles de entender están listadas en el cuadro siguiente. Table 1. Opciones de la shell bash Opción cdspell Efecto Intenta corregir palabras mal escritas de los nombres de directorios cuando utiliza el comando incorporado cd. expand_aliases Habilita alias de shell extglob Habilita sintaxis coincidente de patrones de comodines extendidos nocaseglob No considera el caso cuando se aplican comodines de archivo. Lo anterior se presenta a manera de ejemplos. Revise la página de manual de bash(1) para obtener una lista completa. A continuación, madonna examina el estado de la opción de shell cdspell, lo habilita y luego el de cd en el directorio /etc con un deletreo descuidado.