Introducción a BASH
Bash es un shell y un lenguaje de scripting. Actúa como interfaz entre el usuario y el sistema operativo, permitiendo a los usuarios ejecutar comandos, scripts y gestionar procesos. Su capacidad para manejar scripts de manera eficiente hace que sea una herramienta poderosa para la automatización de tareas, administración del sistema y desarrollo de software.
Características básicas
Para utilizar el valor de una variable la prefijaremos con el carácter $
:
Redirección
Los comandos tienen una entrada y una salida. A la hora de ejecutar cada comando, podemos alterar su entrada y salida utilizando una notación especial reconocida por la shell. Cada redirección puede venir precedida por un descriptor de archivo en forma de número o palabra. Podemos ver los descriptores de archivos dentro de /dev/fd/
.
Existen diferentes descriptores:
0
: Representa la entrada estándar o STDIN.1
: Representa la salida estándar o STDOUT.2
: Representa la salida estándar de errores o STDERR.- Del
3
al9
: Reservados para abrir archivos adicionales.
Los operadores de redirección sólo pueden usarse con un argumento; es decir, sólo puede haber un descriptor de entrada y un descriptor de salida. Si se intenta utilizar múltiples descriptores del mismo tipo, Bash producirá un error.
Operadores de salida estándar
El operador de redirección >
se utiliza para redirigir la salida de un comando a un archivo. Si no añadimos este operador, por defecto se utilizará el descriptor /dev/fd/1
.
La siguiente sintaxis command > filename
redirigirá la salida estándar producida por el comando command
al archivo filename
. Es equivalente a escribir command 1> filename
.
Caben destacar dos aspectos importantes de esta sintaxis:
- Si el archivo no existe, será creado.
- Si el archivo existe, su contenido será reemplazado por la salida del comando.
$ ls
$ echo "Contenido del archivo" > archivo.txt
$ ls
archivo.txt
$ cat archivo.txt
Contenido del archivo
Veamos qué ocurre si utilizamos la misma redirección pero con otro contenido:
$ ls
archivo.txt
$ echo "Ahora el contenido es diferente" > archivo.txt
$ ls
archivo.txt
$ cat archivo.txt
Ahora el contenido es diferente
El operador >>
realiza la misma operación que >
, con la diferencia de que añade el contenido de la salida estándar al contenido del archivo en vez de reemplazarlo. Es equivalente a escribir command 1>> filename
.
$ ls
archivo.txt
$ echo "Esta es una nueva línea" >> archivo.txt
$ cat archivo.txt
Ahora el contenido es diferente
Esta es una nueva línea
Si escribimos un 2
delante del comando de redirección, indicaremos que queremos cambiar la salida estándar de errores a un archivo:
$ ls archivo.txt archivo_inexistente.txt
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
-rw-rw-r-- 1 usuario usuario 48 Ago 29 20:33 archivo.txt
$ ls -l archivo.txt archivo_inexistente.txt > archivo-estadisticas.txt
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
$ cat archivo-estadisticas.txt
-rw-rw-r-- 1 usuario usuario 48 Ago 29 20:33 archivo.txt
Para redirigir STDERR a un archivo:
$ ls -l archivo.txt archivo_inexistente.txt 2> archivo-errores.txt
$ cat archivo-errores.txt
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
Podemos redirigir tanto STDERR como STDOUT a diferentes archivos:
$ ls -l archivo.txt archivo_inexistente.txt > archivo-estadisticas.txt 2> archivo-errores.txt
$ cat archivo-estadisticas.txt
-rw-rw-r-- 1 usuario usuario 48 Ago 29 20:33 archivo.txt
$ cat archivo-errores.txt
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
Para redirigir ambos STDOUT y STDERR a un mismo archivo, usamos la sintaxis command &> filename
:
$ ls -l archivo.txt archivo_inexistente.txt &> archivo-todo.txt
$ cat archivo-todo.txt
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
-rw-rw-r-- 1 usuario usuario 48 Ago 29 20:33 archivo.txt
También podemos redirigir la salida a /dev/null
para suprimirla:
$ ls archivo.txt archivo_inexistente.txt > /dev/null
ls: no se puede acceder a 'archivo_inexistente.txt': No such file or directory
$ ls archivo.txt archivo_inexistente.txt &> /dev/null
archivo.txt
Operadores de entrada
El operador <
se utiliza para redirigir la entrada al archivo descriptor de la izquierda con el contenido del archivo de la derecha. La siguiente sintaxis command < filename
(equivalente a command 0< filename
) leerá el archivo filename
y volcará su contenido en el STDIN del comando.
$ echo -e "Esta es la primera línea\nEsta es la segunda línea" > archivo.txt
$ grep "primera" < archivo.txt
Esta es la primera línea
$ grep "tercera" < archivo.txt
Heredocument
Un Heredocument permite pasar múltiples líneas de entrada a un comando sin tener que crear un archivo. Su sintaxis es la siguiente:
command << DELIMITER
TU TEXTO
CON MÚLTIPLES
LÍNEAS
DELIMITER
La palabra DELIMITER
puede ser cualquier palabra que quieras, y se utiliza para indicar el final del heredocument.
$ grep "primera" << EOF
Esta es la primera línea
Esta es la segunda línea
EOF
Esta es la primera línea
Si el contenido tiene variables, se sustituyen a menos que las prefijemos con \
o encerremos el delimitador del heredoc entre comillas simples '
:
$ cat > tips.txt << EOF
Para saber el directorio actual podemos usar la variable \$PWD
Ahora mismo estoy en $PWD
EOF
$ cat tips.txt
Para saber el directorio actual podemos usar la variable $PWD
Ahora mismo estoy en /home/usuario
Pipelines
Una pipeline o pipe adjunta la salida estándar (STDOUT) de un proceso a la entrada estándar (STDIN) de otro. La sintaxis es la siguiente:
<command1> <...args> | <command2> <...args> | <command3> <...args> ...
$ curl -s http://metaphorpsum.com/sentences/3 | wc -w
33
$ curl -s http://metaphorpsum.com/paragraphs/3 | grep -io "the" | wc -l
Brace expansion
Brace expansion genera cadenas de texto utilizando las llaves {
y }
con caracteres separados por comas:
$ echo file{1,2,3}
file1 file2 file3
$ mkdir folder-{a,b,c}
$ cp file.txt{,.backup}
Puedes crear combinaciones de múltiples expansiones:
$ echo {a,b,c}{1,2,3,4}
a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4
Expansión aritmética
Con el operador $
y doble paréntesis, podemos realizar operaciones aritméticas:
$ echo $((34 * 10))
340
$ echo $((24 == 24))
1
Expansión de nombre de archivos
Utiliza caracteres especiales para crear patrones que Bash escaneará para encontrar archivos que coincidan.
El asterisco *
coincide con cualquier número de caracteres:
$ ls folder*
folder-a:
folder-b:
folder-c:
El interrogante ?
coincide con un carácter:
$ touch tip{,o,s}.txt
$ ls -l tip?.txt
-rw-rw-r-- 1 usuario usuario 0 Sept 4 16:57 tipo.txt
-rw-rw-r-- 1 usuario usuario 88 Sept 4 16:57 tips.txt
Corchetes [ ]
permiten coincidir caracteres específicos:
$ touch tiph.txt
$ ls -l tip[oh].txt
-rw-rw-r-- 1 usuario usuario 0 Oct 4 17:00 tiph.txt
-rw-rw-r-- 1 usuario usuario 0 Oct 4 16:57 tipo.txt