Conceptos Básicos de BASH: Introducción a BASH - Parte 5

Nuestra aventura con la programación continúa con más tests, declaraciones if, entradas y funciones; También haremos cálculos desde dentro de BASH. Primero, vamos a echar s un vistazo a la manipulación del nombre de archivo, ya que parece ser una de las cosas más comunes que son necesarias en los scripts de principiantes. A modo bonificación por sobrevivir a esta gran cantidad de teoría, dispondremos de otro ejemplo de programación BASH en forma de juego.

Nombre base

Los primeros scripts que la gente suele escribir son para gestionar y manipular archivos. Tener que hacer simples tareas una y otra vez, como las conversiones, se vuelve aburrido muy rápido. Es natural que incluso las personas reacias a los scripts intenten automatizar esta cuestión tardo o temprano. Normalmente, esto implica guardar el resultado con el mismo nombre de archivo pero con una extensión diferente, por ejemplo, convertir file001.png en file001.jpg luego, file002, file003 y así sucesivamente.

¿Y en qué nos puede ayudar BASH?

Si abres el manual de bash, con man bash, en algún lugar de las casi 6000 líneas del manual, similar a las 35 partes de la serie BASH que estás leyendo en este momento, encontrarás una sección sobre “Sustitución de parámetros”. Te voy a evitar tener que desplazarte por todo esto, existe un truco muy útil para manejar largas páginas del manual:

$ man -P "less -p 'Parameter Expansion'" bash
Esto salta directamente a la sección que estás buscando, si recuerdas las palabras clave adecuadas. Vamos a resumir un poco nuestros hallazgos, ya que la página del manual es bastante más árida que mi artículo y es tan concisa que tienes que leerla varias veces para lograr sacar algo en claro. La variable escrita por costumbre $foo es una abreviatura, la versión completa es ${foo}, que también es una versión corta, de $ {foo: operators}. ¿Qué significa esto? Veamos algunos de estos supuestos y luego seguiremos con algunos ejemplos. Se pueden colocar dos operadores dentro de las llaves, # y %. Se pueden utilizar como caracteres individuales o en pareja. Las combinaciones posibles son:

  • Para recortar el sufijo más corto dese el final: $ {variable%patrón}
  • Para recortar el sufijo más largo desde el final: $ {variable %% patrón}
  • Para recortar el prefijo más corto desde el principio: ${variable#patrón}
  • Para recortar el prefijo más largo desde el principio: ${variable##patrón}

La diferencia entre "más corto" y "más largo" solo se aplica si está utilizando un comodín Shell * en tu patrón, para algo como jpg, son idénticos. Ahora necesitamos algunos ejemplos para entender cómo funciona esto. Como mejor se aprende es haciendo cosas, puedes experimentar con el comando echo y varias variables shell. Si quieres continuar con el ejemplo, crea una ruta /tmp/odroid con mkdir -p/tmp/odroid, seguido de /tmp/odroid/photos.zip para crear un archivo vacío para te experimento. No es necesario seguir línea por línea, aunque para tu experimento, es mejor tener algo que puedas manejar con facilidad. Aquí tienes los resultados:

Si tenemos la variable

foo="/tmp/odroid/photos.zip"
(No olvide las comillas para asegurarte de que puedes gestionar espacios y otros caracteres especiales complejos) Puedes usar

  • foo=/tmp/odroid/photos.zip"; echo "${foo%/*}" para mostrar la ruta /tmp/odroid. Este es un método fácil para obtener el correspondiente nombre de directorio de un archivo.
  • foo=/tmp/odroid/photos.zip"; echo "${foo##*/}" genera photos.zip, el nombre base del archivo.
  • foo=photos.zip"; file="${foo%%.*}" proporciona photos, y foo=photos.zip"; echo "${foo#*/}" proporciona zip.

Otra aplicación útil de los paréntesis es la expansión de los mismos. Por ejemplo, si deseas hacer un archivo de copia de seguridad de algo, pero eres demasiado vago para escribir la ruta completa y el nombre de archivo del origen y del destino: cp /path/to/your/file.doc{,.bak} se amplia a cp /path/to/your/file.doc /path/to/your/file.doc.bak y hace un archivo de copia de seguridad de tu documento en el mismo directorio. ${#foo} proporciona el número de caracteres de la variable. foo=4-letter-word; echo ${#foo} is 13.

Declaraciones if y tests

Para ver en detalle las declaraciones if y tests, recurriremos a un script de ejemplo con todos los bloques básicos que pueden aparecer, tal y como se muestra a continuación:

#!/bin/bash  #Start of every BASH script
# Basic if statement # Comment, script purpose
if [ $1 -gt 9 ]  #test condition and if statement
then
    echo $1, that\'s unusual for a lucky number.  # if statement true
    date  # if statement true
fi
Pwd  #always executed
then
    date
else
    pwd
...
El fragmento anterior podría ser parte de un script de este tipo. También hay if - elif - else o la abreviatura de la sentencia 'else if', sentencias de casos, o la opción de múltiples tests con las condiciones AND u OR con los operadores && para AND y || para OR, aunque esto está fuera del alcance de este artículo. Los corchetes, [], en la declaración if anterior son una referencia al comando test. Aquí también se pueden usar todos los operadores que test permita. Localiza la página de manual sobre test para ver todos los operadores posibles; Algunos de los más comunes se enumeran a continuación.

  • ! EXPRESSION - La EXPRESSION es falsa.
  • -n STRING - La longitud de STRING es mayor que cero.
  • -z STRING - La longitud de STRING es cero (= está vacío).
  • STRING1 = STRING2 - STRING1 es igual a STRING2
  • STRING1 != STRING2 - STRING1 no es igual a STRING2
  • INTEGER1 -eq INTEGER2 - INTEGER1 es numéricamente igual a INTEGER2
  • INTEGER1 -gt INTEGER2 - INTEGER1 es numéricamente mayor que INTEGER2
  • INTEGER1 -lt INTEGER2 - INTEGER1 es numéricamente menor que INTEGER2
  • -d FILE - FILE eexiste y es un directorio.
  • -e FILE - FILE existe.
  • -r FILE - FILE existe y el permiso de lectura está concedido.
  • -s FILE - FILE existe y su tamaño es mayor que cero (= no está vacío).
  • -w FILE - FILE existe y el permiso de escritura esta concedido.
  • -x FILE - FILE existe y el permiso de ejecución esta concedido.

Entrada, mas variables

Para la entrada BASH, si quieres tener un script interactivo, puede usar ‘read’ para leer la variable desde la entrada del usuario. Simple script de ejemplo, greeting.sh:

echo Who are you?
read name
echo It\'s nice to meet you, $name.
Puesto que las comillas tienes un significado especial en BASH, Éste logra escaparse a través de la barra invertida. read -p y read -sp se pueden usar para solicitar y guardar silencio, lo que significa no repetir la entrada escrita:
read -p 'Username: ' user
read -sp 'Password: ' pass
Almacena el nombre de usuario en $user y la contraseña en $pass, sin mostrarlo. Si el usuario introduce varias palabras cuando se le solicite, read varx vary varz almacenaría tres palabras en las tres variables diferentes. Si son más de tres palabras, la última variable almacena la entrada restante. Aquí tienes algunas variables especiales que puedes usar en tus scripts:

  • $0 - El nombre del script Bash.
  • $1 - $9 - Los primeros 9 argumentos del script Bash.
  • $# - Número de argumentos pasados al script Bash.
  • $@ - Todos los argumentos ofrecidos al script Bash.
  • $? - El estado de salida del proceso ejecutado recientemente.
  • $$ - El ID de proceso del script actual.
  • $USER - El nombre de usuario del usuario que ejecuta el script.
  • $HOSTNAME - El hostname de la máquina en la que se ejecuta el script.
  • $SECONDS - El número de segundos desde que se inició el script.
  • $RANDOM - Devuelve un número aleatorio diferente cada vez que se hace referencia.
  • $LINENO - Devuelve el número de la línea actual en el script Bash.

Estos deberían ser bastante simples, con $0 necesitan algo más de detalle: con esto, puedes hacer que tu script actúe de manera diferente según el nombre que utilices, por ejemplo, comprimir y descomprimir archivos. Hay disponible una lista completa de variables predefinidas que puedes usar si escribes ‘env’ en la línea de comando.

Con esto, ahora existen 3 métodos para pasar datos a un script BASH, y cuál de ellos es el mejor método depende de la situación:

  • Argumentos de línea de comando, como ourscript.sh foo bar baz proporciona $1=foo, $2=bar and $3=baz.
  • Leer la entrada durante la ejecución del script, véase antes.
  • Datos que han sido redirigidos al script mediante stdin. Esto es más para programadores experimentados, básicamente, es lo mismo que canalizar los resultados de otro script o función hacia nuestro script con ‘|’.

Usamos comillas a veces sin explicar para qué sirven. Como BASH usa un espacio para separar los elementos, device = Odroid XU4; echo $device emite un mensaje de error que indica que no se puede encontrar 'XU4', porque el contenido de la variable es solo 'Odroid' y BASH intenta ejecutar 'XU4'. Si quieres una variable con espacios, necesitas usar comillas. El texto entre comillas indica a BASH que los contenidos deben considerarse como un solo elemento. Puede usar comillas simples ‘ o dobles ". Dependiendo de lo que quiera hacer, cualquiera de las dos es importante:

  • Las comillas simples procesa literalmente todos los caracteres. echo 'I am $USER' devuelve I soy $USER.
  • Las comillas dobles te permitirán realizar sustituciones (es decir, incluir variables que son valoradas). echo "I am $USER" devuelve yo soy odroid.

También puede usar la sustitución de comandos para tener una variable rellena con la valoración de los comandos - foo=$(ls/etc | wc -l); echo Hay entradas $foo en /etc. Muestra cuántas entradas de configuración hay en tu directorio /etc.

Si deseas tener variables disponibles para otros scripts, debes exportarlas. export foo hace que $foo esté disponible para los siguientes scripts, pero si cambian $foo, no tendrá ningún impacto en el script de exportación. Piensa en ello como cuando haces una copia y la distribuyes.

Cálculos

Vamos a tratar los cálculos en BASH brevemente. Bastante es saber que $ ((...)) evalúa el término entre corchetes dobles. De modo que, si quieres saber rápidamente cuántos segundos tiene un año, escribe:

$ echo $((60*60*24*365))
Esto debería devolver 31536000. Sin embargo, solo se permiten valores enteros. Esto es así para la entrada de datos y el resultado - BASH calcula el resultado fraccionado a la baja. echo $ ((4/5)) da 0, y solo echo $ ((5/5)) le dará 1 como resultado.

Aplicación práctica de BASH

Otro juego como recompensa por sobrevivir a todos los aspectos teóricos de BASH, en torno a 350 líneas de scirpt BASH tiene el juego 2048. Puede jugarlo con las teclas de cursor, el enlace al script lo tienes en las referencias. Descárgalo con wget.

Esta ha sido una extensa y magnífica información, en la siguiente parte nos tomares un respiro en relación a la teoría y analizaremos algunas aplicaciones de línea de comandos interesantes y unos cuantos scripts BASH útiles. También un poco más (¡solo un poco!) de programación con bucles y funciones.

Referencias

http://linuxg.net/curly-brackets-expansion-in-bash-with-5-practical-examples/ https://raw.githubusercontent.com/mydzor/bash2048/master/bash2048.sh

Be the first to comment

Leave a Reply