Semana 4 y_5_-_la_shell_bash

50 %
50 %
Information about Semana 4 y_5_-_la_shell_bash

Published on March 12, 2014

Author: victdiazm

Source: slideshare.net

La shell bash 1 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.

La shell bash 2 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

La shell bash 3 # .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/

La shell bash 4 168 ls -Rli 169 exit 170 171 exit 172 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 Sintaxis Sustitución !! 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

La shell bash 5 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).

La shell bash 6 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;

La shell bash 7 } [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]$ mkdir bin [madonna@station madonna]$ chmod 700 <ESC-.> [madonna@station madonna]$ mv hello <ESC-.> [madonna@station madonna]$ ls <ESC-.> hello 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

La shell bash 8 [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.

La shell bash 9 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 elvis]$ cd /etc/X11; ls applnk prefdm sysconfig xorg.conf.backup xkb desktop-menus proxymngr twm xorg.conf.wbx Xmodmap fs rstart X xorg.conf.works Xresources gdm serverconfig xdm XftConfig.README-OBSOLETE xserver lbxproxy starthere xorg.conf xinit xsm [elvis@station X11]$ El efecto es idéntico al escribir comandos en líneas separadas. [elvis@station elvis]$ cd /etc/X11 [elvis@station X11]$ ls applnk prefdm sysconfig xorg.conf.backup xkb desktop-menus proxymngr twm xorg.conf.wbx Xmodmap fs rstart X xorg.conf.works Xresources gdm serverconfig xdm XftConfig.README-OBSOLETE xserver lbxproxy starthere xorg.conf xinit xsm [elvis@station X11]$ 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

La shell bash 10 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 elvis]$ (cd /etc/X11; ls) applnk prefdm sysconfig xorg.conf.backup xkb desktop-menus proxymngr twm xorg.conf.wbx Xmodmap fs rstart X xorg.conf.works Xresources gdm serverconfig xdm XftConfig.README-OBSOLETE xserver lbxproxy starthere xorg.conf xinit xsm [elvis@station elvis]$ 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]$ bash [elvis@station elvis]$ cd /etc/X11; ls applnk prefdm sysconfig xorg.conf.backup xkb desktop-menus proxymngr twm xorg.conf.wbx Xmodmap fs rstart X xorg.conf.works Xresources gdm serverconfig xdm XftConfig.README-OBSOLETE xserver lbxproxy starthere xorg.conf xinit xsm [elvis@station X11]$ exit exit [elvis@station 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).

La shell bash 11 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,

La shell bash 12 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, load average: 0.35, 0.27, 0.18 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT student_a tty1 - Mon23 ?xdm? 2:43m 3.06s /bin/bash student tty2 :0.0 Tue17 0.00s 2.19s 0.00s /bin/sh/home/student/bin/wdate.sh [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.

La shell bash 13 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

La shell bash 14 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 $?

La shell bash 15 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

La shell bash 16 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 local share tmp dict games kerberos libexec sbin src X11R6 [elvis@station elvis]$ 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.

La shell bash 17 • 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

La shell bash 18 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.

La shell bash 19 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 .plan .. .bashrc .kde .txt .bash_history .gnome-desktop ode_to_apple.txt .viminfo .bash_logout .gnupg .pgpkey .xauthizv2EF [prince@station prince]$ cat .txt Oh, I like them squishy 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.

La shell bash 20 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:interactive- comments: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

La shell bash 21 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

La shell bash 22 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

La shell bash 23 BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release" [5]="i386-redhat- linux-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 Uso TERM 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.

La shell bash 24 [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 Links supports the use of proxy servers that can act as firewall gateways and caching servers. They are preferable to the older gateway servers (see WWW_access_GATEWAY, below). Each protocol used by Links, (http, ftp, gopher, etc), can be mapped sepa- rately 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.

La shell bash 25 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

La shell bash 26 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]$ ls -l /usr/sbin/lsof -rwxr-xr-x 1 root root 95640 Jan 24 2003 /usr/sbin/lsof [prince@station prince]$ lsof -c init -bash: lsof: command not found 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 init COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root mem REG 3,3 27036 245377 /sbin/init init 1 root mem REG 3,3 104560 244833 /lib/ld-2.3.2.so init 1 root mem REG 3,3 1536292 476416 /lib/tls/libc- 2.3.2.so 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

La shell bash 27 init 1 root mem REG 3,3 104560 244833 /lib/ld-2.3.2.so init 1 root mem REG 3,3 1536292 476416 /lib/tls/libc- 2.3.2.so 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

La shell bash 28 [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.

La shell bash 29 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 Sintaxis Se expande hasta Historial ! 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/

La shell bash 30 `-- 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 prince]$ ls -ld ~ ~elvis drwx-----x 15 elvis elvis 4096 Jul 21 17:41 /home/elvis drwx-----x 9 prince prince 4096 Aug 4 06:58 /home/prince [prince@station prince]$ ls -l ~elvis/pub total 4 drwxrwxr-x 2 elvis music 4096 Jul 13 05:46 music

La shell bash 31 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

La shell bash 32 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&quo

Add a comment

Related presentations

Related pages

Semana 4 y 5 - La Shell Bash - scribd.com

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.
Read more

Semana 4 y 5 - La Shell Bash - pt.scribd.com

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.
Read more

Semana 4 y 5 -La Shell Bash Guia de Ejercicios Resuelta

Semana 4 y 5 -La Shell Bash Guia de Ejercicios Resuelta - Download as PDF File (.pdf), Text File (.txt) or read online.
Read more

Semana 4 y 5 - La Shell Bash - Documents

Semana 4 y 5 la shell bash guia de ejercicios resuelta 1. La shell bash 1 Capítulo 1 Introducción a Bash Conceptos clave • La shell por defecto en Red ...
Read more

Semana 4 y 5 - Documents

Semana 4 y 5 La cultura desde diversas perspectivas teóricasExperiencia de aprendizaje 4 y 5En ... Semana 4 y 5 la shell bash guia de ejercicios ...
Read more

Semana 4 y 5 - La Shell Bash - es.scribd.com

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.
Read more

Semana 4 y 5 -La Shell Bash Guia de Ejercicios Resuelta ...

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 ...
Read more