Bash (consola/terminal)#
Introducción#
La consola (o terminal) de Linux es muy útil. Como se mencionó en la introducción a Linux, se puede acceder a una consola a través de la combinación de teclas CTRL
+ALT
+t
, y utilizar mecanismos como los portapapeles de Linux, además de sus atajos de teclado propios. Nótese que, al igual que Linux en general, Bash es "sensible a mayúsculas" (al contrario que en Windows, sí hace diferencia el hecho de que una misma letra se escriba con minúscula o mayúscula).
Atajos de teclado#
tab
: autocompletado a partir de lo escrito (es necesario pulsar dos veces si hay existen opciones).- flecha
arriba
/abajo
: moverse a través de historial de comandos. CTRL-r
: búsqueda de comandos escritos anteriormente (pulsar y empezar a teclear).
Símbolos especiales#
En esta sección se comentan algunos símbolos especiales. En los ejemplos se utilizan los comandos ls
(listar contenido de carpeta) y cd
(cambiar de carpeta) que se explican con mayor detalle en la sección de comandos útiles.
/
Se utiliza como delimitador entre nombres de carpetas, y entre nombres de carpetas y archivos (equivalente en Windows:\
). Por ejemplo:/etc/crontab
indica que dentro de la carpeta/etc
hay un fichero que se llamacrontab
..
Significa "aquí", "en esta carpeta". Por su cuenta, muchas veces se puede omitir (ls .
se puede abreviar comols
, ycd .
no hace nada).- Se utiliza cuando se quiere especificar una ruta relativa. Por ejemplo:
/etc
es una ruta absoluta, se refiere una carpetaetc
en la raíz del sistema de ficheros; sin embargo,./etc
es una ruta relativa, se refiere a una carpetaetc
dentro de la carpeta donde estamos. - Se utiliza cuando se quiere lanzar un programa no instalado. Se trata de un caso de uso específico del punto anterior. Cuando un programa no está propiamente instalado (por ejemplo, acabamos de compilar
miPrograma
), uno está obligado a especificar que se quiere ejecutar el de la carpeta donde se está (siguiendo con el ejemplo:./miPrograma
). - También se utiliza dentro del nombre de un fichero, para separar
nombre.extensión
. - Por último, como se comentó en la introducción, el
.
al inicio de un nombre de fichero indica fichero oculto, y esto sucede con muchos ficheros de configuración.
- Se utiliza cuando se quiere especificar una ruta relativa. Por ejemplo:
..
Significa "en la carpeta padre", "la carpeta que contiene esta carpeta". Por ejemplo, ascendemos a la carpeta padre viacd ..
.*
Significa "cualquier cosa", es un operador "comodín". Por ejemplo:ls ab*
nos da un listado de todo lo que empieza porab
, yls *png
nos da un listado de todoque finalice (nombre completo, incluyendo extensión) enpng
.?
Significa "cualquier cosa", es un operador "comodín", pero limitado a una sola letra o carácter. Se pueden poner varios seguidos.#
Significa "comentario", no se ejecuta lo que esté a su derecha. Por ejemplo:ls # Esto es un comentario
hace lo mismo quels
, pero aporta información al lector. Nótese que aunque no se ejecute como tal, puede contener información relevante, véase el Shebang en la sección de scripts de Bash.\
La barra inversa (backslash) tiene dos usos (su equivalente en Windows:^
(caret)):- Interpretar como literal. Por ejemplo: mediante
ls Mis\ Documentos
se evita el uso de entrecomillado del texto (interpreta el espacio () como literalmente un espacio en lugar de como separador de argumentos/parámetros).
- Se utiliza para trocear un comando en varias líneas, indicando que el comando continúa. Funciona sólo si no se introducen caracteres adicionales a su derecha (aunque en realidad lo que se está introduciendo es una nueva línea, y el mecanismo subyacente es el del caso anterior).
- Interpretar como literal. Por ejemplo: mediante
;
Se puede utilizar para escribir varios comandos en la misma línea (equivalente en Windows:&
).&&
Similar al anterior, para escribir varios comandos en la misma línea, pero sólo si va bien el primero se ejecuta el segundo (equivalente en Windows:&&
igual)."
Este tipo de entrecomillado permite espeficicar que un texto va en bloque, pese a la presencia de espacios. Por ejemplo:cd "Mis Documentos"
.- ` Este tipo de entrecomillado permite utilizar la salida estándar (STDOUT, que por defecto se muestra por pantalla) de un programa como argumento de otro. Por ejemplo:
cd
`ls
` intentaría cambiar de carpeta utilizando el nombre de la primera entrada del listado dels
(y daría error en caso de que fuese un fichero en lugar de una carpeta). |
Se llama pipe. Redirige la salida estándar (STDOUT, que por defecto se muestra por pantalla) de un programa a otro programa. Es similar pero de uso algo menos intuitivo que el entrcomillado `. Por ejemplo, para salidas estándar muy largos y sin posibilidad de scroll de ratón, se utiliza:ls | less
, dondeless
permite el avance con la teclaEnter
y salir conq
. En otras ocasiones está desaconsejado (don't pipe the cat, 1).>
Redirige la salida estándar (STDOUT, que por defecto se muestra por pantalla) de un programa, a un fichero. Si el fichero ya existe, primero borra su contenido. Por ejemplo:ls > stdout.log
vuelca el listado de contenido de la carpeta donde se está creando un fichero llamadostdout.log
. Hemos seleccionadolog
porque se traduce como "registro de actividades", pero puede usarse cualquier extensión o incluso omitirse.>>
Similar a>
, pero si el fichero ya existe, anexa los datos a continuación de los datos existentes.2>
Redirige la salida de errores (STDERR, que por defecto se muestra por pantalla) de un programa, a un fichero. Si el fichero ya existe, primero borra su contenido. Por ejemplo:cd
`ls
`2> stderr.log
vuelca el error (en caso de producirse) creando un fichero llamadostderr.log
. Existe un fichero muy especial,/dev/null
, que quiere decir "a ninguna parte" (se traduce como "no me muestre usted los errores"), y se puede utilizar:cd
`ls
`2> /dev/null
2>>
Similar a>
, pero si el fichero ya existe, anexa los datos a continuación de los datos existentes.2>&1
Otra variante de2>
, redirige a donde se dirija lo de>
. Existe1>&2
para el caso inverso.<
Por ejemploprograma < file.txt
utiliza el contenido defile.txt
como la entrada estándar (STDIN, que normalmente sería el teclado, deprograma
durante su ejecución.&
Lanza un programa en segundo plano, por ejemplo:programa &
. Muestra el identificador de proceso (PID) al lanzar el programa. Se puede listar los programas en segundo plano mediante el comando jobs, o pasar el programa a primer plano mediante el comando fg.!$
Contiene la última palabra que uno mismo ha escrito en la consola, similar a la variable de entorno_
(ref).$
Para obtener el valor de una variable de entorno.~
Se corresponde con la variable de entornoHOME
. Por ejemplo,ls ~
yls $HOME
son equivalentes.
Estos símbolos se pueden combinar en el mismo comando y en cualquier orden, como por ejemplo: programa & 2> /dev/null
lanza programa
en segundo plano, y además evita que no nos estén llegando mensajes de error (que sería el comportamiento por defecto): véase cómo lo utilizamos aquí.
El comando man
#
El comando man
proporciona el manual del comando nombrado. Por ejemplo, con man ls
se accede al manual del comando ls
.
Dentro de un manual, se puede buscar con /
(esto es como en vim).
Por ejemplo, con /--size
se puede obtener información del parámetro --size
si estamos viendo el manual de ls
.
Los manuales de man
se componen de diferentes secciones, del 1 al 8, porque no sólo se refieren a comandos de consola.
Por ejemplo, la sección 3 se centra en la librería C estándar (y además muestra el #include necesario).
Se puede forzar el ir a la entrada de una sección, por ejemplo man 3 scanf (aunque funcionaría sin el 3 al no tratarse de una entrada duplicada).
Se sale del manual con la tecla q
.
Un comando muy similar a man
es info
, que en ocasiones propoorciona mejor documentación.
Listado alfabético de comandos útiles#
Estos comandos, en general, también son aplicables a gnome-terminal
, bash
, sh
, xterm
...
- apt-cache search: en Debian/Ubuntu/Mint, da el nombre de los paquetes que contienen los metadatos que se buscan (versión, dependencias, descripción, etc.).
- apt-file search: en Debian/Ubuntu/Mint, da el nombre de los paquetes que contienen el fichero que se busca.
- apt-get install: en Debian/Ubuntu/Mint, instala un paquete, que puede ser un programa o librería (e.g. de nombre liblibrería-dev). Suele requerir sudo delante.
- cat: Escribe el contenido de un fichero por pantalla. Útil para echar un vistazo rápido a un fichero que ni merece la pena abrir para editar. Por ejemplo:
cat README.md
vuelca el contenido del ficheroREADME.md
. Para ficheros largos, mejor utilizar head (donde una opción buena eshead -n 5 README.md
para ver sólo primeras 5 líneas) o tail (para ver últimas líneas, véase también su uso en dmesg). Curiosamente, para ver una línea específica, es mejor sed víased -n 5p README.md
o rangosed -n 5,7p README.md
(más usos en su sección abajo). Nota: Su nombre proviene de su uso original, para concatenar, por ejemplo:cat file1.txt file2.txt > new.txt
- cd: cambiar de carpeta.
- cp: copiar origen a destino. Una alternativa que muestra progreso y mantiene permisos es
rsync -ah --progress origen destino
(ojo: su comportamiento difiere según/
al final de la ruta)(para crear respaldos puede ser interesante recursivo y eliminando los ficheros que no existen en el origen:rsync -rah --progress --delete origen destino
). - crontab: Edita la tabla de tareas periódicas mediante
crontab -e
. - diff: Compara ficheros y carpetas.
colordiff
existe como variante con colores (omeld
como cliente gráfico). - df: Mostrar ocupación de discos montados. Utilícese con
-lh
para lectura humana. - dmesg: Muestra mensajes del kernel. Utiliza
tail -f /var/log/syslog
para verlo en stream continuo. - du: Mostrar ocupación de subcarpetas. Utilícese con
-lh
para lectura humana, y-s
para resumido. - echo: Escribe una cadena de caracteres por pantalla. Útil en scripts de bash. Por ejemplo:
echo "hola mundo"
escribehola mundo
en pantalla. - find: Busca ficheros que cumplan un criterio (nombre, tamaño...).
- Uso básico (buscar fichero por nombre):
find -name fichero.txt
- Uso básico (buscar fichero con comodín, ejemplo extensión):
find -name *.txt
- Buscar fichero por nombre sin importar mayúsculas/minúscula:
find -iname fichero.txt
- Buscar fichero por nombre delimitando la profundidad de carpetas entre las cuales se busca:
find -maxdepth 2 -name fichero.txt
- Véase también su uso en la sección dedicada a bucles en bash.
- Uso básico (buscar fichero por nombre):
- free: Mostrar memoria (RAM) libre. Utilícese con
-lh
para lectura humana. - grep: Busca texto contenido en ficheros.
- Uso básico:
grep "cadena de texto" fichero.txt
- En todos los ficheros de una carpeta:
grep "cadena de texto" *
- En todos los ficheros de una carpeta y sus subcarptas (
r
de recursivo):grep -r "cadena de texto" *
- En todos los ficheros de una carpeta y sus subcarptas (
i
de case-insensitive) sin importar mayúsculas/minúsculas de la cadena:grep -ri "cadena de texto" *
- En todos los ficheros con extensión
.cpp
de una carpeta y sus subcarptas sin importar mayúsculas/minúsculas de la cadena:grep -ri "cadena de texto" --include *.cpp
- Mostrar líneas a continuación de las encontradas:
grep -A 1 "cadena" *
- Mostrar número de línea en el cual aparece:
grep -n "cadena" *
- Mostrar fichero completo marcando cadena en color:
grep --color -E "cadena|$" fichero.txt
- Invertir búsqueda (encontrar lo que no lleve cadena):
grep -v "anti cadena" *
- Manteniendo color pese a cruzarse con un pipe
|
:grep --color=always "cadena" * | grep -v "anti cadena"
- Modo regular expressions extendido, permite
|
modo "OR" lógico (al ser dentro de la cadena, no es un pipe) y así buscar simultánemente:grep -E "uno|dos
- Uso básico:
- killall: Intenta matar a un proceso, por nombre. Puedes utilizar
pkill
en su lugar para nombre incompleto. Por defecto, envía una señal POSIX de tipoSIGTERM
(15), que es algo más brusco queSIGINT
(2, típico deCTRL-C
), sin llegar al extremo deSIGKILL
(9). Se puede meter la señal como parámetro:killall -s 9 nombre
(leer más: 1,2; listado señales:kill -l
). Aquí una alternativa más compleja, metiendo el identificador de proceso (PID de por medio:pgrep "nombre" | xargs kill -s 9
. - locate: Parecido al find. Busca ficheros de forma general y rápida porque usa la base de datos de updatedb.
- ls: Listar contenido de carpeta,
ls -lh
para tamaños con lectura humana. Existen otros muchosls
:lscpu
,lsmod
... utilizals
y tabulador para autocompletado para descubrirlos. - mkdir: crear una carpeta
- mv: mover origen a destino
- rename:
--no-act 's/^imagen/image/' *
(donde^
implica sólo al principio)) - rm: borrar (con
-r
para recursivo (entra en subcarpetas),-rf
recursivo forzado)) - sed: Se puede utilizar reemplazar texto en un fichero (utilizar con cuidado!!!).
- Previsualización (vuelca por pantalla sin realizar cambios):
sed "s/viejo/nuevo/g" fichero.txt
- Uso básico:
sed -i "s/viejo/nuevo/g" fichero.txt
- En todos los ficheros de una carpeta:
sed -i "s/viejo/nuevo/g" *
- No tiene funcionalidad recursiva (en todos los ficheros de una carpeta y sus subcarptas), pero se puede conseguir mediante bucles en bash.
- Previsualización (vuelca por pantalla sin realizar cambios):
- setxkbmap: Cambiar la configuración del teclado. Por ejemplo, a español:
setxkbmap es,es
(sin X, pero que requieresudo
:loadkeys --verbose es
) - sudo: Realizar el comando que se escribe en la misma línea con permisos de administrador.
- top: Mostrar los processos en ejecución (donde (PID es el identificador de proceso, y COMMAND es el nombre del proceso). Con colores, existe
htop
. - tree: Mostrar contenidos de una carpeta en formato árbol. Con
-L
se puede especificar la profundidad (p.ej.tree -L 2
). Con-I
se puede excluir un patrón (p.ej.tree -I build
) o varios patrones (p.ej.tree -I "build|__pycache__"
). - uname: Información de bajo nivel, incluida la versión de kernel de Linux y arquitectura/provesadores si se invoca:
uname -a
. - updatedb: Actualiza la base de datos que utiliza locate
- wget: Descarga un fichero, con
-O
se puede renombrar. Es lo que utilizamos aquí.
Bucles en Bash#
Existen diversas maneras de iterar en Bash:
- A través del comando
find -exec
. El operador{}
se refiere al objeto encontrado, que puede ponerse entre comillas"{}"
para prevenir frente a espacios en nombres. Por último, se utiliza\;
para lanzar el comando una vez por incidencia (estilocomando file1; comando file2; comando file3;
), o\+
para concatenar (juntar secuencialmente en una sola línea, estilocomando file1 file2 file3
). Ejemplos:- Ejemplo 1: Cambiar a permisos
664
todos los ficheros (-type f
) de una carpeta y sus subcarpetas:find -type f -exec chmod 664 {} \; # find -type f -exec chmod 664 {} + # alternativa 1, concatenando # find -type f -print0 | xargs -0 chmod 664 # alternativa 2, puede ser más rápido
- Ejemplo 2: Cambiar a permisos
775
todas las carpetas (-type f
) de una carpeta y sus subcarpetas:find -type d -exec chmod 775 {} \; # find -type d -exec chmod 775 {} + # alternativa 1, concatenando # find -type d -print0 | xargs -0 chmod 775 # alternativa 2, puede ser más rápido
- Ejemplo 3: Copiar todo lo que contenga "cadena" en su nombre a otra carpeta:
find -name "*cadena*" -exec cp {} /carpeta/destino \;
- Ejemplo 4: En todos los ficheros (
-type f
) de una carpeta y sus subcarpetas, aplicarsed
:find -type f -exec sed -i 's/viejo/nuevo/g' {} \+
- Ejemplo 5: Por cada carpeta que contenga una carpeta
.svn
, aplicarsvn up {}
done{}
es cada ruta encontrada (omitiendo.svn
viased
):find -name ".svn" | sed "s/.svn//g" | xargs svn up
- Ejemplo 1: Cambiar a permisos
- A través de bucles
for
.- Ejemplo 1 (que se podría realizar en una línea única):
for fileName in "$(find -name *.mp3)"; do printf "$fileName\n"; done
- Ejemplo 2: Renombrar con fecha delante, separado por guión:
for f in *; do mv -- "$f" "$(date -r "$f" +%Y%m%d)-$f"; done
- Ejemplo 1 (que se podría realizar en una línea única):
Scripts de Bash#
Un Script de Bash (Bash Script) es un conjunto de comandos de consola de linux que el sistema operativo ejecuta en orden. Script se suele traducir como fichero de ejecución por lotes.
Nótese que si la complejidad de un Script es muy elevada:
- Tal vez se pueda simplificar 1
- Se puede considerar utilizar un script de Python en su lugar, puesto que a costa de su intérprete se consiguen muchas más herramientas y en general una sintaxis más sencilla.
Cualquier Script de Linux debería tener un Shebang como primera línea. La primera línea de un Script de Bash debería ser #!/usr/bin/env bash
(1).
Se pueden encontrar algunos ejemplos de Scripts de Bash en la sección de ficheros de configuración. Nota: al tratarse de ficheros de sistema, en general no necesitan Shebang.