COMANDOS

shellPodemos ejecutar dos tipos de comandos desde el interior del script shell. Existen comandos “normales” que podría ejecutar también desde el incitador de comandos (denominados comandos externos), y existen comandos que “incluye el programa” (denominados comandos internos), tal como se comentó previamente. Los comandos incluidos en el programa se ejecutan dentro de la shell y no se pueden invocar como programas externos. Sin embargo, la mayoría de comandos internos también están disponibles como programas independientes, exigencia que forma parte de la llamada POSIX, Normalmente no importa si el comando es externo o interno, pero los comandos internos se ejecutan con mayor eficacia.

Veamos a continuación los principales comandos tanto internos como externos que usamos al programar los scripts. Recuerde siempre que, además de los comandos que incluye el programa, puede utilizar cualquier comando en un scriptbreak.-Use break para escapar de un bucle for, while o until cerrado antes de que se cumpla la condición de control. Puede proporcionar a break un parámetro numérico adicional, que será el número de partida de los bucles, pero esto puede dificultar la lectura de los scripts, por eso no le aconsejamos su uso. Por defecto break escapa a un único nivel.

  •  break.-Use break para escapar de un bucle for, while o until cerrado antes de que se cumpla la condición de control. Puede proporcionar a break un parámetro numérico adicional, que será el número de partida de los bucles, pero esto puede dificultar la lectura de los scripts, por eso no le aconsejamos su uso. Por defecto break escapa a un único nivel.
  • El comando de los dos puntos (:) es nulo. En algunas ocasiones resulta útil para simplificar la lógica de las condiciones, ya que actúa como alias de true. Aparece con el programa, por eso : se ejecuta más rápido que true, a pesar de que su salida es mucho menos legible. Es posible que lo vea como condición de los bucles while; while : ejecuta un bucle infinito en vez del bucle while true, más común. La construcción : también resulta útil en la configuración condicional de las variables. Por ejemplo:figura_dospuntosSin los dos puntos :, la shell intentará evaluar $var como un comando.nota_dospuntosdospuntos_escript
  • continue .- Este comando hace que los bucles for, while o until continúen hasta la siguiente iteración, y que la variable del bucle adopte el siguiente valor de la lista:

    continue_scriptcontinue puede adoptar el número del bucle de cierre en el cual continuar como un parámetro opcional de manera que podamos salirnos parcialmente de los bucles anidados. Este parámetro no se suele usar, ya que dificulta la comprensión de los script. Por ejemplo:

    continue2_script

    La salida del script sería:

    continue2_salida

  • El comando punto (.).- El comando punto (.) ejecuta el comando de la shell actual:

    comando_punto

    Normalmente, cuando un script ejecuta un comando externo o un script, se crea un nuevo entorno (subshell), el comando se ejecuta en dicho nuevo entorno, y después el entorno se elimina del código de salida que vuelve a la shell padre. Sin embargo el source externo y el comando punto ejecutan los comandos de un script en la misma shell que llamó al script.Porque, por defecto, cuando se ejecuta un script shell se crea un nuevo entorno, se pierde cualquier modificación de las variables de entorno que realice el script. Sin embargo, el comando punto permite que el script ejecutado modifique el entorno actual. Esto resulta útil cuando usa un script a modo de envoltorio para configurar su entorno con el fin de ejecutar posteriormente algún otro comando.

    El siguiente ejemplo usa el comando punto en la línea de comando, pero también puede usarlo simplemente como un script:

    1.- Imagine que tiene dos archivos que contienen las opciones de entorno de dos entornos de desarrollo diferentes. Para configurar el entorno de los comandos antiguos, los más clásicos, clasic_set, podría usar:

    comando_punto_script1

    2.- Para los comandos nuevos use latest_set:

    comando_punto_script2

    Puede configurar el entorno usando estos scripts junto al comando punto, al igual que en la siguiente sesión a modo de ejemplo:

    comando_punto_salida

    Cómo funciona

    Estos scripts se ejecutan usando el comando punto, de manera que cada script se ejecuta en la shell actual, que conserva los cambios incluso cuando el script deja de ejecutarse.

  • eval .- El comando eval le permite evaluar argumentos. Se encuentra dentro de la shell y no suele aparecer como comando externo. Veamos un breve ejemplo de la propia especificación X/Open:com_eval1Proporciona la salida $foo. Sin embargo,com_eval2envía 10. Por eso, eval es un poco como un $ adicional: le proporciona el valor del valor de una variable. El comando eval es muy útil, permite que se genere código y que se ejecute sobre la marcha. Dificulta la localización de errores, pero le permite realizar tareas que de otra manera sería muy difícil o imposible.
  • exec.- El comando exec tiene dos usos diferentes. Normalmente, se usa para reemplazar la shell actual por un programa diferente. Por ejemplo:exec_ejemplo1en un script reemplazará la shell actual con el comando wall. Tras exec no se procesará ninguna línea del script, porque la shell que ejecutaba el script no existe.El segundo uso de exec es modificar los descriptores del archivo actual:execejemplo2El ejemplo hace que el descriptor de archivo tres se abra para leerlo desde el archivo afile. Apenas se usa.
  • exit n.- El comando exit hace que el script envía un código de salida n. Si lo usa en el incitador de comandos de cualquier shell interactivo, le sacará del sistema. Si permite que un script salga sin especificar un estado de salida, se usará entonces como valor de retorno del estado del último comando ejecutado en el script. Le recomendamos que proporcione siempre un código de salida. En lo referente a programación de scripts shell, el código de salida 0 indica éxito, y los códigos del 1 al 125, ambos inclusive, son códigos de error que pueden usar los scripts. El resto de valores tienen significados reservados, tal como mostramos en la siguiente tabla:tabla_codigo_salidaA muchos programadores de C o C++ les resultará extraño usar cero para indicar éxito. La gran ventaja de los scripts es que permiten usar 125 códigos de error definidos por el usuario sin tener que usar una variable de código de error global.Este sencillo ejemplo envía éxito si un archivo denominado Ejemplo1 aparece en el directorio actual:exit_ejemplo_scriptPodemos escribir este script usando la lista combinada AND y OR, todo esto en una sola línea:exit_ejemplo_script2
  •  export.- El comando export hace que la variable que comparte nombre con su parámetro esté disponible en las subshells. Por defecto, las variables creadas en una shell no están disponibles para el resto de (sub) shells que invoca dicha shell. El comando export crea una variable de entorno a partir de su parámetro que puede ser vista por otros scripts y programas que hayan sido invocados desde el programa actual. Técnicamente, son las variables exportadas desde las variables de entorno en cualquier proceso hijo que derive de la shell. Lo veremos mejor con un ejemplo que formaremos con dos scripts export1 y export2. Primeramente crearemos el archivo export2:ejemplo_export2Ahora crearemos export1. Al final del script ejecutará export2:ejemplo_export1Al ejecutarlo obtendremos:

    export_salida

    Funcionamiento: El script export2 se hace eco de los valores de las dos variables. El script export1 establece ambas variables, pero sólo marca a bar como exportada, de manera que cuando invoca a export1 más tarde, el valor de foo se ha perdido, pero el valor de bar se ha exportado al segundo script. La línea en blanco aparece porque $foo no evalúa nada, y al hacerse eco de la variable null aparece una nueva línea.Una vez que se ha exportado una variable de una shell, se exporta a todos los scripts invocados desde esa shell y a su vez a toda shell que invoque, y así continuamente. Si el script export2 llama a otro script, también dispondrá del valor bar.

    nota_export

  •  expr.- El comando expr evalúa sus argumentos con una expresión.Se suele usar para la aritmética sencilla de la siguiente forma:expr_ejemplo1Los tics invertidos (` `) hacen que x ejecute el comando expr $x +1. También podemos escribirlo usando la sintaxis $() en vez de los tics invertidos:expr_ejemplo2El comando expr es potente y puede realizar muchas evaluaciones de expresiones. A continuación mostramos los principales:expr_tablaEn los scripts más modernos, el uso de expr se suele reemplazar por una sintaxis $ ((...)) más eficiente, que estudiaremos más adelante.
  • printf .- El comando printf sólo está disponible en las shell más recientes. X/Open surgió que debería usarse antes que echo para generar las salidas formateadas, pero parece que pocos han seguido el consejo.La sintaxis es:

    printf_ejemplo1

    La cadena de formato es muy similar a la usada en C o C++, con algunas restricciones. Principalmente, no se acepta el punto flotante, porque toda la aritmética de la shell se ejecuta como enteros. La cadena de formato  está compuesta por una combinación de caracteres literales, de secuencias de escape y de especificaciones de conversión. Todos los caracteres de la cadena que no sean % y \ aparecen literalmente en los datos de salida. Se aceptan las secuencias de escape de la tabla de abajo:

    secuencias_de_escape_tablaEl especificador de conversión es bastante complejo, por eso vamos a comentar únicamente los más usados. En el manual básico online podrá encontrar más información, así como en las páginas printf de la sección 1 del manual online (man 1 printf). (Si no lo encontramos en la sección 1 del manual, inténtelo en la sección 3). El especificador de conversión está compuesto de un carácter %, seguido de un carácter de conversión. Las principales conversiones aparecen en la siguiente tabla:

    printf_tabla2

    La cadena de formato se usa después para interpretar el resto de parámetros y para enviar el resultado, tal como  mostramos en el siguiente ejemplo:

    ejemplo_printfAl omitir la secuencia de escape \n al final, vemos que el prompt de comando aparece a continuación de la salida del comando printf. Vamos a corregir el problema:

    ejemplo2_printfTenga en cuenta que debe usar las cadenas con comillas (” “) para proteger la cadena Estamos las y convertirla en un único parámetro.

  • return y set
    RETURN

    El comando return cumple las mismas funciones que el retorno, tal como mencionamos al estudiar las funciones previamente, return adopta un parámetro numérico único que está disponible para el script que llama a la función. Si no se especifica parámetro alguno, return adopta el código de salida del último comando.

    set

    El comando set configura las variables de parámetro de la shell. Puede ser un modo útil para usar campos en comandos que envían valores separados por comas.

    Imagine que queremos usar el nombre del mes actual en un script shell. El sistema proporciona un comando date, que contiene el mes a modo de cadena, pero tiene que separarlo del resto de campos. Lo puede hacer usando una combinación del comando set y de la construcción $(...), y así podrá ejecutar el comando date y retornar el resultado (que en breve describiremos con todo detalle). La cadena del mes es el segundo parámetro de la salida del comando date:

    ejemplo1_setEste programa configura la lista de parámetros de la salida del comando date y después usa el parámetro posicional $2 para obtener el mes.

    set_resultadoTenga en cuenta que usamos el comando date a modo de sencillo ejemplo para mostrarle como extraer parámetros posicionales. Como el comando date es sensible ante los escenarios lingüísticos, en realidad habría extraído el nombre del mes usando date +%B. El comando date dispone de muchas otras opciones de formato, véase el manual para obtener más información.

    También puede usar el comando set para controlar el modo de ejecución de la shell mediante la transmisión de parámetros. La forma más usada del comando es set -x, que hace que un script muestre una traza del comando que se está ejecutando en ese momento. Cuando nos ocupemos de la localización y solución de errores estudiaremos set y algunas de sus opciones.

  • shift .- El comando shift reduce en uno a todas las variables de parámetro, de manera que $2 se convierte en $1, $3 pasa a ser $2 y así sucesivamente. $0 no varía, por eso el valor anterior de $1 desaparece. Si al llamar a shift se especifica un parámetro número, los parámetros se mueven todos esos espacios. El resto de las variables $*, $@ y $# también se modifican en línea con la nueva disposición de variables de parámetro.shift suele ser útil para escanear los parámetros transmitidos en un script, y si su script requiere 10 o más parámetros, necesitará shift para acceder al décimo y posteriores.Por ejemplo, podemos escanear todos los parámetros posicionales de esta manera:ejemplo_shift
  • trap .- El comando trap se usa para especificar las acciones a realizar cuando se reciban las señales, que estudiaremos más adelante en este capítulo. Se suele emplear para ordenar un script cuando éste es interrumpido- Tradicionalmente, las shells siempre usaban un número para las señales, pero los scripts nuevos usan nombres que toman del archivo #include signal.h, con el prefijo SIG omitido. Para ver los números de señal y los nombres asociados, puede escribir trap -l en un incitador de comandos.

    ejemplo_trap

    nota_trap

    Al comando trap se le transmite la acción que hay que falsificar, seguido del nombre de la señal (o de los nombres) que hay que retener:

    trap_ejemplo2

    Recuerde que los scripts se suelen interpretar desde el principio hasta el final, por eso debe especificar el comando trap antes de la parte del script que desea proteger.

    Para restablecer una condición trampa, sólo tiene que especificar el comando como -. Para ignorar una señal, establezca el comando como una cadena vacía ' '. Un comando trap sin parámetros imprime la lista actual de trampas y acciones.

    trap_ejemplo3Veamos la siguiente tabla que enumera las señales más importantes que contiene el estándar X/Open y que se puede atrapar (con el número de señal convencional entre paréntesis). Podemos obtener más información en el manual online de las páginas de consulta signal (man 7 signal)

    señales_tablaSeñales

    El siguiente script presenta una gestión de señal sencilla:

    ejemplo_trap_scriptSi ejecutamos este script, mantenga presionado la tecla CTRL y presione después la tecla C en cada uno de los bucles y obtendrá el siguiente resultado:

    bucle_trapCómo funciona

    Este script usa el comando trap para solicitar que se ejecute el comando rm -f /tmp/my_file_$$ cuando tenga lugar una señal INT (interrupción). Después, el script introduce un bucle while que continua mientras exista el archivo. Cuando el usuario presiona CTRL-C, la sentencia rm /tmp/my_tmp_file_$$ se ejecuta, y después reanuda el bucle while. Como el archivo ha sido eliminado, el primer bucle while termina sin problemas.

    Posteriormente, el script usa de nuevo el comando trap, esta vez para especificar que cuando tenga lugar una señal INT no se ejecute ningún comando. Después recrea el archivo y hace un bucle dentro de la segunda sentencia while. Esta vez, cuando el usuario presione CTRL-C, como no se ha configurado ninguna sentencia para que se ejecute, tendrá lugar el comportamiento predeterminado que finalizará de manera inmediata el script. Como el script finaliza de manera inmediata, las sentencias finales echo y exit no se ejecutará nunca.

  • unset .- El comando unset elimina variables y funciones del entorno. No puede hacerlo con las variables de lectura definidas por la propia shell, como IFS, No se suele usar.

    El siguiente script de ejemplo escribe Hola mundo una vez y una línea nueva la segunda vez:

    e3jemplo_unset

    nota_unset

COMANDOS NO SHELL:

  • find .- El primer comando que veremos es find. Dicho comando, se usará para buscar archivos, resulta extremadamente útil, pero a los principiantes en Linux les puede resultar un poco complicado, no solo porque tiene opciones, comprobación y argumentos del tipo acción, sino también los resultados de un argumento pueden afectar a los resultados de los argumentos posteriores.Antes de meternos en materia con las opciones, en las comprobaciones y en los argumentos, vamos a estudiar un sencillo ejemplo del archivo test en su ordenador local. Hágalo como root para asegurarse de que dispone de los permisos necesarios para rastrear todo el sistema.salida_find

    Dependiendo de su instalación, posiblemente encuentra otros muchos archivos llamados test que empieza con / y después mostrar el nombre del archivo en pantalla. Parece fácil.

    Sin embargo, nos llevará un tiempo ejecutarlo en nuestro ordenador si compartimos Linux con Windows en la red temblará. Esto se debe a que nuestro sistema Linux se superpone (usando SAMBA) a una parte de nuestro sistema de archivos de Windows. Es como si también se hubiese rastreado, aunque nosotros sabemos que el archivo que buscamos estaba en sistema Linux.

    find_ejemplo2

    Esta vez volveremos a encontrar el archivo en nuestro sistema, pero mucho más rápido, y sin rastrear otros sistemas de archivos superpuestos.

    La sintaxis completa del comando find es:

    find_ejemplo3

    La parte [path] es sencilla podemos usar la ruta absoluta, como /bin, o una ruta relativa, como .. Si fuese necesario, tambien puede especificar múltiples rutas, por ejemplo find /var /home.

    [opciones].- Hay muchas opciones, las principales las vemos en la siguiente tabla:

    find_opciones

    Se puede proporcionar a find un gran número de comprobaciones,  y todas las pruebas envían true o false. Cuando find está trabajando, tiene en cuenta, uno por uno, todos los archivos que se encuentra y aplica todas las comprobaciones, según el orden de definición de dicho archivo. Si una prueba envía false, find abandona el archivo en el que está trabajando y sigue con el siguiente. Si la prueba envía true, find lleva cabo la siguiente comprobación a acción en el archivo actual. Las pruebas que aparecen en la siguiente tabla son las más comunes,

    find_test

    También podemos combinar estas pruebas usando operadores. La mayoría tiene dos formas: la abreviada y la completa, como mostramos en la tabla siguiente:

    find_operadores

    Puede configurar la preferencia de comprobaciones y operadores usando paréntesis. Como tiene un significado especial para la shell, debe entrecomillar también los corchetes usando una barra invertida. Además, si usa un patrón para el nombre de archivo, debe también usar comillas para que el nombre no se expanda por la shell sino que se transmita directamente al comando find. Por ejemplo, si quiere escribir la comprobación “más nuevo que el archivo X o con un nombre que comience con un guión bajo”, podría escribir:

    find_ejemplo4

    Uso de find con comprobaciones

    Intente buscar, en el directorio actual, los archivos que se han modificado más tarde que dospuntos:

    find_con_comprobaciones

    Tiene buena apariencia, pero encontrará el directorio actual no deseado. lo único que nos interesa son los archivos regulares. Añada un test adicional, -type f:

    En el caso del resultado de arriba no aparece ningún directorio con lo que la salida estándar será la misma.

    find_comofunciona

    Ahora que podemos buscar archivos con confianza, observemos las acciones que podemos realizar cuando encuentre un archivo que se corresponda con su especificación. Véase la tabla siguiente:

    find_acciones

    Los comandos -exec y -ok adoptan los parámetros posteriores en la línea como parte de sus parámetros, hasta terminar con una secuencia \;. Efectivamente, los comandos -exec y -ok ejecutan un comando insertado, de manera que dicho comando ha de terminar con un punto y coma de escape, para que así pueda terminar el comando find cuándo debería dejar de buscar opciones en la línea de comando que están pensadas para sí mismas. La cadena mágica ” { } ” es un tipo de parámetro especial para un comando -exec o -or y es reemplazado por la ruta completa del archivo actual.

    Veamos lo con un ejemplo para entender la explicación, veremos que usa un comando seguro como ls:

    find_salida_ejemplo1

    Como puede ver, el comando find es muy útil. Practique con este comando para ir adquiriendo soltura en su uso.

  • grep .- Este comando de gran utilidad tiene un nombre poco usual que se refiere a general regular expression parser. Para rastrear el sistema en busca de archivos usamos find, y para rastrear los archivos en busca de cadenas usamos grep. De hecho, cuando se usa find, se suele transmitir también grep a modo de comando detrás de -exec.

    El comando grep tiene opciones, un patrón que cumplir, y archivos en los que buscar:

    grep_ejemplo1Si no especificamos ningún nombre de archivo, rastrea las entradas estándar. Echemos un vistazo a las principales opciones más usadas de grep:

    grep_opcionesEl uso básico de grep lo veremos con estos ejemplos de algunas correspondencias básicas:

    Este ejemplo no usa opciones, simplemente busca la cadena “soy” en el archivo palabra.txt y muestra cualquier línea que cumpla dicho requisito. El nombre de archivo no aparece porque la búsqueda la hacemos en un solo archivo.

    grep_basicoEste ejemplo recuenta el número de líneas que cumplen el requisito en dos archivos diferentes. En este caso, si que muestra el nombre del archivo.

    grep_cuentalineasFinalmente, usa la opción -v para invertir la búsqueda y contabilizar las líneas de los archivos que no cumplen el patrón.

    grep_linea_3Veamos las expresiones regulares que nos permiten realizar una correspondencia más sofisticada:

    grep_expresiones_regularesSi desea usar alguno de estos caracteres como “caracteres normales”, debe incluir \ delante. Por ejemplo, si desea buscar un carácter $ literal, debería usar \$. También existen caracteres de correspondencia muy útiles que se pueden usar entre corchetes, tal como describimos en la tabla de abajo.

    grep_correspondenciaAdemás, si se especifica -E para la correspondencia extendida, la expresión regular puede ir seguida de otros caracteres que controlan la fiscalización de la correspondencia (véase la siguiente tabla). Con grep también hace falta añadir \ delante de los caracteres.

    grep_caracteresEl modo más sencillo para comprender las expresiones regulares es poner el conocimiento en práctica. Vallamos paso a paso:

    1. En primer lugar buscaremos en las líneas que acaben en s usando el carácter especial $:grep_ejemploPodemos ver que nos muestra las líneas acabadas en s.
    2. Imagine que queremos encontrar palabras que terminen con la letra a. Para hacerlo tiene que usar los caracteres de correspondencia especiales entre paréntesis. En este caso, puede usar [[:blank:]], que busca espacios en blanco o tabuladores.grep_ejemplo2
    3. Ahora busque palabras de tres letras que empiecen por vid. En este supuesto necesita [[:space:]] para delimitar el final de la palabra y . para buscar un carácter adicional único:grep_ejemplo3
    4. Finalmente, el modo grep ampliado para buscar palabras en minúscula que tengan exactamente 9 caracteres. Lo hacemos especificando un rango de caracteres de la a a la z, y una repetición de 9 correspondencias:grep_ejemplo4En este apartado simplemente hemos estudiado más o menos las partes importantes de las expresiones regulares. El mejor modo de ir aprendiendo es mediante la práctica.

    atras

 

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: