Página principal » cómo » La guía para principiantes de Shell Scripting 2 para bucles

    La guía para principiantes de Shell Scripting 2 para bucles

    Si desea construir su credito geek, únase a nosotros para la segunda entrega de nuestra serie de scripts de shell. Tenemos algunas correcciones, algunas mejoras en el guión de la semana pasada y una guía sobre el bucle para los no iniciados..

    El script de datecp revisado

    En la primera entrega de nuestra guía de shell scripting, creamos un script que copiaba un archivo a un directorio de respaldo después de agregar la fecha al final del nombre de archivo.

    Samuel Dionne-Riel señaló en los comentarios que hay una manera mucho mejor de manejar nuestras referencias variables.

    Los argumentos están separados por espacios en el shell bash, se tokenizará cuando haya un espacio en el comando expandido resultante. En tu guion, cp $ 1 $ 2. $ date_formatted funcionará según lo previsto, siempre y cuando las variables expandidas no tengan espacios en ellas. Si llamas a tu script de esta manera: datecp "mi antiguo nombre" "mi nuevo nombre" la expansión dará como resultado este comando: cp mi nuevo nombre mi antiguo nombre.la_fecha que en realidad tiene 6 argumentos.

    Para abordar adecuadamente este problema, la última línea del script debe ser: cp "$ 1" "$ 2. $ date_formatted"

    Como puedes ver, cambiando la línea de nuestro script desde:

    cp -iv $ 1 $ 2. $ date_formatted

    a:

    cp -iv “$ 1” “$ 2”. $ date_formatted

    se ocupará de este problema al usar el script en archivos que tengan espacios en el nombre. Samuel también señala que al copiar y pegar el código de este sitio (o de Internet en general) asegúrese de sustituir los guiones y citas correctos por los "tipográficamente mejores" que a menudo los reemplazan. También haremos más para asegurarnos de que nuestro código sea más fácil de copiar / pegar. ;-)

    Otro comentarista, Myles Braithwaite, decidió expandir nuestro script para que la fecha apareciera antes de la extensión del archivo. Así que en lugar de

    tastyfile.mp3.07_14_11-12.34.56

    obtendríamos esto:

    tastyfile.07_14_11-12.34.56.mp3

    lo que termina siendo un poco más conveniente para la mayoría de los usuarios. Su código está disponible en su página de GitHub. Echemos un vistazo a lo que usa para separar el nombre de archivo.

    date_formatted = $ (fecha +% Y-% m-% d_% H.% M% S)
    file_extension = $ (echo "$ 1" | awk -F. 'print $ NF')
    nombre_archivo = $ (nombre base $ 1. $ extensión_archivo)

    cp -iv $ 1 $ file_name- $ date_formatted. $ file_extension

    He cambiado un poco el formato, pero puedes ver que Myles declara su función de fecha en la Línea 1. Sin embargo, en la Línea 2 usa el comando "echo" con el primer argumento del script para mostrar el nombre del archivo. Él usa el comando pipe para tomar esa salida y usarla como entrada para la siguiente parte. Después de la tubería, Myles invoca el comando "awk", que es un potente programa de exploración de patrones. Utilizando el indicador -F, le dice al comando que el siguiente carácter (después de un espacio) es lo que definirá el "separador de campo". En este caso, eso es un período..

    Ahora, awk ver un archivo llamado "tastyfile.mp3" como compuesto de dos campos: "tastyfile" y "mp3". Por último, utiliza

    'print $ NF'

    para visualizar el último campo. En caso de que su archivo tenga varios períodos, por lo que awk puede ver múltiples campos, solo mostrará el último, que es la extensión del archivo..

    En la Línea 3, crea una nueva variable para el nombre del archivo y usa el comando "basename" para hacer referencia a todo en $ 1 excepto la extensión de archivo. Esto se hace usando basename y dándole $ 1 como argumento, luego agregando un espacio y la extensión del archivo. La extensión del archivo se agrega automáticamente debido a la variable que hace referencia a la Línea 2. Lo que esto haría es tomar

    tastyfile.mp3

    y convertirlo en

    archivo sabroso

    Luego, en la última línea, Myles juntó el comando que generará todo en orden. Tenga en cuenta que no hay referencia a $ 2, un segundo argumento para el script. Este script en particular copiará dicho archivo en su directorio actual. Gran trabajo Samuel y Myles!

    Ejecutando Scripts y $ PATH

    También mencionamos en nuestro artículo Básicos que los scripts no pueden ser referenciados como comandos de forma predeterminada. Es decir, debes apuntar a la ruta del script para ejecutarlo:

    ./guión

    ~ / bin / script

    Pero, al colocar sus scripts en ~ / bin /, puede escribir sus nombres desde cualquier lugar para que se ejecuten..

    Los comentaristas dedicaron un tiempo a debatir qué tan apropiado era esto, ya que ninguna distribución moderna de Linux crea ese directorio de forma predeterminada. Además, nadie lo agrega a la variable $ PATH por defecto, que es lo que se requiere para que los scripts se ejecuten como comandos. Estaba un poco desconcertado porque después de verificar mi variable $ PATH, los comentaristas tenían razón, pero las secuencias de comandos de llamada aún funcionaban para mí. Descubrí por qué: muchas distribuciones modernas de Linux crean un archivo especial en el directorio de inicio del usuario: .profile.

    Este archivo se lee con bash (a menos que .bash_profile esté presente en el directorio de inicio del usuario) y en la parte inferior, hay una sección que agrega la carpeta ~ / bin / a la variable $ PATH si existe. Entonces, ese misterio se aclara. Para el resto de la serie, continuaré colocando scripts en el directorio ~ / bin / porque son scripts de usuario y los usuarios deberían poder ejecutarlos. Y parece que realmente no necesitamos meternos con la variable $ PATH a mano para que las cosas funcionen..

    Repitiendo comandos con bucles

    Vayamos a una de las herramientas más útiles en el arsenal geek para hacer frente a tareas repetitivas: los bucles. Hoy, estaremos discutiendo "para" bucles.

    El esquema básico de un for-loop es el siguiente:

    para VARIABLE en LISTA; hacer
    comando1
    comando2
    ...
    comando
    hecho

    VARIABLE puede ser cualquier variable, aunque la mayoría de las veces se utiliza la "i" minúscula por convención. LISTA es una lista de artículos; puede especificar varios elementos (separándolos por un espacio), apuntar a un archivo de texto externo o usar un asterisco (*) para indicar cualquier archivo en el directorio actual. Los comandos enumerados están sangrados por convención, por lo que es más fácil ver el anidamiento: colocar bucles en bucles (para que pueda hacer bucles mientras bucea).

    Debido a que las listas utilizan espacios como delimitadores, es decir, un espacio significa un movimiento al siguiente elemento de la lista, los archivos que tienen espacios en el nombre no son muy amigables. Por ahora, sigamos trabajando con archivos sin espacios. Comencemos con un simple script para mostrar los nombres de los archivos en el directorio actual. Cree un nuevo script en su carpeta ~ / bin / titulado "loopscript". Si no recuerdas cómo hacerlo (incluyendo marcarlo como ejecutable y agregar el hack del hash bang), consulta nuestro artículo de conceptos básicos de scripts de bash..

    En ella, ingresa el siguiente código:

    para i en item1 item2 item3 item4 item5 item6; hacer
    echo "$ i"
    hecho

    Cuando ejecute el script, debería obtener esos elementos de la lista como salida.

    Bastante simple, ¿verdad? Vamos a ver qué pasa si cambiamos las cosas un poco. Cambia tu guión para que diga esto:

    para i en *; hacer
    echo "$ i"
    hecho

    Cuando ejecute este script en una carpeta, debería obtener una lista de los archivos que contiene como salida.

    Ahora, cambiemos el comando echo a algo más útil, por ejemplo, el comando zip. A saber, vamos a agregar archivos en un archivo. Y, vamos a obtener algunos argumentos en la mezcla!

    para i en $ @; hacer
    archivo zip "$ i"
    hecho

    ¡Hay algo nuevo! “$ @” Es un atajo para “$ 1 $ 2 $ 3… $ n”. En otras palabras, es la lista completa de todos los argumentos que especificó. Ahora, observe lo que sucede cuando ejecuto el script con varios archivos de entrada.

    Puedes ver qué archivos están en mi carpeta. Ejecuté el comando con seis argumentos, y cada archivo se agregó a un archivo comprimido llamado "archive.zip". Fácil a la derecha?

    Porque los bucles son bastante maravillosos. Ahora puedes ejecutar funciones por lotes en listas de archivos. Por ejemplo, puede copiar todos los argumentos de su script en un archivo comprimido comprimido, mover los originales a una carpeta diferente y proteger de forma automática la copia de ese archivo zip en una computadora remota. Si configura archivos clave con SSH, ni siquiera necesitará ingresar su contraseña, e incluso puede decirle al script que elimine el archivo zip después de cargarlo!


    El uso de for-loops facilita la realización de un montón de acciones para todos los archivos en un directorio. Puede apilar una amplia variedad de comandos y usar argumentos muy fácilmente para crear una lista sobre la marcha, y esto es solo la punta del iceberg.

    Bash scripters, ¿tienes alguna sugerencia? ¿Has hecho un script útil que usa bucles? ¿Quieres compartir tus pensamientos sobre la serie? Deja algunos comentarios y ayuda a otros novatos en scripting.!