Diferencia entre revisiones de «Scripts Bash»

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda
Línea 119: Línea 119:
  let ContLin++ # Contando...  
  let ContLin++ # Contando...  
  echo -n "$Num " # -n para no saltar línea  
  echo -n "$Num " # -n para no saltar línea  
  ((ContLin % 10)) > /dev/null || read '''< /dev/tty'''
  ((ContLin % 10)) > /dev/null || read
  done < numeros
  done < numeros



Revisión del 10:12 29 abr 2013

Redirecciones

$ cmd > fichero

Redirige la salida estandar a un fichero.

$ cmd 2> fichero

Redirige la salida de error a un fichero.

$ cmd >> fichero

Añade a un fichero la salida estandar sin borrar el contenido anterior.

$ cmd 2>> fichero

Añade los errores al final de un fichero.

$ cmd &> fichero

Redirige la salida estandar y la de error a un fichero.

$ cmd > fichero 2>&1

Otra manera de redirigir las dos salidas a un fichero.

$ cmd > /dev/null
$ cmd 2> /dev/null
$ cmd &> /dev/null

Descartar la salida estándar, la de error o las dos.

$ cmd < fichero

Redirige el contenido de un fichero a la entrada estandar del comando.

$ cmd << FIN 
linea1 
linea2 
FIN 

Redirige una serie de líneas a un comando. Esto se llama Here-Document. La palabra FIN sólo es para indicar el final de las líneas y puede ser cualquier otra.

$ cmd <<< "palabra"

Redirecciona el texto al comando. Se llama here-string.

$ exec 2> fichero

Redirige la salida de error a un fichero para todos los comandos.

$ exec 3< fichero

Abre un fichero para leer usando un nuevo descriptor.

$ exec 3> fichero 

Abre un fichero para escribir usando un nuevo descriptor.

$ exec 3<> fichero 

Abre un fichero para leer o escribir usando el descriptor 3.

$ exec 3>&-

Cierra un descriptor de fichero.

# open it
exec 3< input.txt

# for example: read one line from the file(-descriptor)
read -u 3 LINE
# or
read LINE <&3

# finally, close it
exec 3<&-


read interactivo de ficheros

$ seq 30 > numeros

Observemos este script:

#!/bin/bash 
# cada 10 linies espera a que l'usuari escriga alguna cosa

while read Num 
do 
	let ContLin++ # Contando... 
	echo -n "$Num " # -n para no saltar línea 
	((ContLin % 10)) > /dev/null || read 
done < numeros 

El resultado es este:

1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30

Y no se espera a que el usuario ponga nada.

Esto es porque el read de dentro del bucle lee también del fichero. Se puede forzar a que lea de la terminal:

#!/bin/bash 
# cada 10 linies espera a que l'usuari escriga alguna cosa

while read Num 
do 
	let ContLin++ # Contando... 
	echo -n "$Num " # -n para no saltar línea 
	((ContLin % 10)) > /dev/null || read < /dev/tty
done < numeros 

O se puede crear un descriptor de fichero y modificar el real del while:

#!/bin/bash 
# cada 10 linies espera a que l'usuari escriga alguna cosa

exec 3< numeros
while read Num <&3
do 
	let ContLin++ # Contando... 
	echo -n "$Num " # -n para no saltar línea 
	((ContLin % 10)) > /dev/null || read
done < numeros

Process Substitution

Los comandos que necesitan un fichero, pueden ejecutarse con el |, por ejemplo el wc puede hacerse:

$ cat /etc/passwd | wc -l

A veces un comando acepta como entrada dos ficheros. En ese caso, el ejemplo anterior no se puede seguir. Para solucionarse, se pueden usar los () después de una < [1]

$ diff <(ls $first_directory) <(ls $second_directory)

Variables y argumentos

  • $0: Nombre del script.
  • $1,$2,$3...$9 Argumentos. En principio no se puede poner más de 9 argumentos. Si se quiere poner 10 o más, se puede recurrir al shift o poniéndolo como ${12}
  • $# Candidad de argumentos
  • $* Todos los argumentos
  • $? : a 0 si el comando anterior ha terminado sin dar error. A 1 o más si ha dado error.
  • $_ : El primer argumento del comando anterior

shift

Este comando permite usar un mismo número de argumento para ir recorriéndolos.

En este ejemplo se ve bastante bien. Via

while test -n "$1"; do
   case "$1" in
       -a)
           opciona=$2
           shift
           ;;
       -b)
           opcionb=$2
           shift
           ;;
       -c)
           opcionc=$2
           shift
           ;;
       -d)
           opciond=$2
           shift
           ;;
       *)
           echo "Unknown argument: $1"
           exit 0
           ;;
   esac
   shift
done

El while recorre todos los argumentos, aunque sólo comprueba el $1 en cada iteración, se queda con $2 y pasa al siguiente. De esta manera, el órden de los argumentos y sus opciones no es relevante.

# miscript -a opciona -b opcionb -d opciond
# miscript -b opcionb -c opcionc

Interpretación de los argumentos por el shell

El shell se encarga de sustituir los caracteres de sustitución y las variables antes de pasar los argumentos a un comando o script. Esto se puede ver con este script:

#!/bin/bash 

echo $*
echo $#

Si se invoca de estas maneras, por ejemplo:

$ ./argumentos *
$ ./argumentos p[a-z]
$ ./argumentos {1..100}
$ ./argumentos $HOME