Comandos GNU y Unix
LPI 103.1 Línea de comandosLPI 103.2 Filtros de textoLPI 103.3 Gestión de ficherosLPI 103.4 Streams, pipes y redireccionesLPI 103.5 ProcesosLPI 103.6 PrioridadesLPI 103.7 Expresiones regularesLPI 103.8 Editor vi
Este es, con diferencia, el tema con más peso de todo el examen 101-500 — y el que más vas a usar el resto de tu vida con Linux delante. No hay atajos: hay que escribir estos comandos cientos de veces hasta que salgan sin pensar. Este capítulo es largo a propósito; vuelve a él tantas veces como haga falta.
- Moverte por la línea de comandos: variables de entorno, historial, ayuda y alias.
- Filtrar y transformar texto con
cut,sort,uniq,tr,sed,awky compañía. - Gestionar ficheros y directorios: copiar, mover, buscar, enlazar y archivar.
- Encadenar comandos con tuberías y redirecciones, incluida la salida de error.
- Crear, vigilar y matar procesos, y ejecutarlos en primer o segundo plano.
- Modificar la prioridad de ejecución de un proceso con
nice/renice. - Buscar patrones de texto con expresiones regulares básicas y extendidas.
- Editar un fichero de texto de principio a fin con
vi, sin ratón y sin salir de la terminal.
1. LPI 103.1 — Trabajar en la línea de comandos
1.1 Variables de entorno y de shell
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin$ export EDITOR=vim$ env | grep -i lang
LANG=es_ES.UTF-8| Comando | Qué hace |
|---|---|
export VAR=valor | Crea/modifica una variable y la hace visible a los procesos hijos |
unset VAR | Elimina una variable |
env | Lista todas las variables de entorno exportadas |
set | Lista variables de entorno y variables locales del shell actual |
$PATH | Lista de directorios donde el shell busca ejecutables, separados por : |
$HOME, $USER, $SHELL, $PWD | Variables estándar que todo shell de login define |
1.2 Historial y edición de la línea de comandos
| Atajo/comando | Qué hace |
|---|---|
history | Lista los comandos ejecutados recientemente, numerados |
!55 | Vuelve a ejecutar el comando número 55 del historial |
!! | Repite el último comando (típico para anteponer sudo: sudo !!) |
Ctrl+R | Búsqueda incremental hacia atrás en el historial |
Ctrl+A / Ctrl+E | Ir al principio / al final de la línea |
Tab | Autocompletado de comandos, rutas y, con muchos programas, de argumentos |
1.3 Ayuda y localización de comandos
$ man ls
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
...$ which python3
/usr/bin/python3$ type cd
cd is a shell builtin$ whereis grep
grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz| Comando | Para qué |
|---|---|
man comando | Manual completo de un comando |
man -k palabra (= apropos) | Busca comandos relacionados con una palabra clave |
info comando | Documentación en formato GNU Info, a veces más detallada que el man |
comando --help | Resumen rápido de opciones, sin salir al paginador |
which comando | Ruta del ejecutable que se lanzaría, según $PATH |
type comando | Indica si es un binario, un alias, una función o un builtin del shell — más completo que which |
whereis comando | Localiza binario, fuente y páginas de manual de un comando |
1.4 Alias
$ alias ll='ls -lah'$ alias
alias ll='ls -lah'
alias grep='grep --color=auto'$ unalias ll~/.bashrc (solo para tu usuario) y recarga con source ~/.bashrc.Practica más — labs ya publicados en Ghost Academy sobre este tema: 🔧 Comandos varios I (lab)
2. LPI 103.2 — Procesar flujos de texto con filtros
Un "filtro" en Unix es un programa que lee de la entrada estándar, transforma algo, y escribe en la salida estándar — pensado para encadenarse con tuberías (sección 4). Esta es la caja de herramientas de texto más usada de todo Linux.
| Comando | Qué hace |
|---|---|
cat | Concatena y muestra ficheros completos |
tac | Como cat, pero con las líneas en orden inverso |
head -n N / tail -n N | Primeras/últimas N líneas |
tail -f fichero | Sigue el fichero en tiempo real — imprescindible para logs |
sort | Ordena líneas (-n numérico, -r inverso, -k por columna, -u elimina duplicados al ordenar) |
uniq | Elimina líneas duplicadas consecutivas — por eso casi siempre va detrás de sort |
wc | Cuenta líneas (-l), palabras (-w) y bytes/caracteres (-c/-m) |
cut | Extrae columnas por posición (-c) o por delimitador (-d ':' -f 1) |
paste | Une líneas de varios ficheros en columnas, lado a lado |
join | Une dos ficheros ordenados por un campo común, como un JOIN de SQL |
tr | Traduce o elimina caracteres carácter a carácter (no trabaja por líneas) |
expand / unexpand | Convierte tabuladores en espacios y viceversa |
fmt | Reajusta el ancho de línea de un texto para que quede legible |
pr | Pagina texto para impresión, con cabeceras y numeración de página |
nl | Numera las líneas de un fichero |
od -c | Vuelca un fichero en octal/hexadecimal — útil para ver caracteres no imprimibles |
split | Trocea un fichero grande en partes más pequeñas |
sed | Editor de flujo: sustituciones y transformaciones línea a línea sin abrir un editor interactivo |
awk | Lenguaje de procesamiento de texto por campos y registros — el más potente de todos |
$ sort /etc/passwd | cut -d: -f1 | head -5
backup
bin
daemon
games
gnats$ cat accesos.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -3
142 203.0.113.9
87 198.51.100.4
51 192.0.2.17cut para extraer la IP, sort para agrupar, uniq -c para contar repeticiones y sort -rn para ordenar de más a menos — es prácticamente el "hola mundo" del análisis de logs en una terminal. Apréndetela de memoria.$ echo 'hola mundo' | tr 'a-z' 'A-Z'
HOLA MUNDO$ sed 's/error/ERROR/g' app.log | head -3
2026-09-30 10:02:11 ERROR: conexión rechazada
2026-09-30 10:02:14 ERROR: timeout tras 30s
2026-09-30 10:03:01 INFO: reintentando$ awk -F: '{print $1, $3}' /etc/passwd | head -3
root 0
daemon 1
bin 2awk -F: '{print $1, $3}' — el -F: fija : como separador de campos, y $1/$3 son el primer y tercer campo de cada línea (usuario y UID en /etc/passwd). El examen pregunta por esta sintaxis de campos ($1, $2... y $0 para la línea completa) con bastante frecuencia.Practica más — labs ya publicados en Ghost Academy sobre este tema: 📝 Redirección y texto I (lab) · 📝 Redirección y texto II (lab) · 📝 Redirección y texto III (lab)
Valida lo aprendido — tests temáticos de Recursos: 📝 Test: Procesamiento de Texto
3. LPI 103.3 — Gestión básica de ficheros
| Comando | Qué hace |
|---|---|
cp origen destino | Copia un fichero (-r para directorios, -p conserva permisos/fechas, -a copia "como es", el modo habitual para backups) |
mv origen destino | Mueve o renombra |
rm fichero | Borra (-r recursivo, -f sin preguntar — combinación peligrosa, piensa dos veces antes de rm -rf) |
mkdir -p ruta/anidada | Crea directorios, incluidos los padres que no existan |
rmdir | Borra un directorio, solo si está vacío |
touch fichero | Crea un fichero vacío, o actualiza su fecha de modificación si ya existe |
find ruta -name patrón | Busca ficheros recursivamente por nombre, tipo, tamaño, fecha... |
locate patrón | Busca por nombre en una base de datos indexada (más rápido que find, pero puede estar desactualizada hasta el siguiente updatedb) |
file fichero | Identifica el tipo real de un fichero por su contenido, no por su extensión |
ln origen enlace | Enlace duro (mismo inodo) |
ln -s origen enlace | Enlace simbólico (un puntero a una ruta) — se detalla en el módulo 104 |
tar | Empaqueta (y opcionalmente comprime) ficheros y directorios |
gzip/gunzip, bzip2, xz | Compresores que tar suele invocar automáticamente con sus propias opciones |
$ find /var/log -name '*.log' -mtime -7
/var/log/apt/term.log
/var/log/auth.log
/var/log/syslog$ find / -size +100M -type f 2>/dev/null
/var/lib/docker/overlay2/.../layer.tar$ file /usr/bin/bash
/usr/bin/bash: ELF 64-bit LSB pie executable, x86-64, dynamically linked$ tar -czvf backup.tar.gz /etc/apache2/
tar: Removing leading `/' from member names
etc/apache2/
etc/apache2/apache2.conf
etc/apache2/sites-available/
etc/apache2/sites-available/000-default.conf$ tar -xzvf backup.tar.gz -C /tmp/restaurado/Flag de tar | Significado |
|---|---|
-c | Crear un archivo nuevo |
-x | Extraer |
-t | Listar contenido sin extraer |
-z | Comprimir/descomprimir con gzip (.tar.gz/.tgz) |
-j | Con bzip2 (.tar.bz2) |
-J | Con xz (.tar.xz) |
-v | Modo detallado (verbose), muestra cada fichero procesado |
-f fichero | Indica el nombre del archivo — casi siempre es la última opción antes del nombre |
Practica más — labs ya publicados en Ghost Academy sobre este tema: 📁 Navegación de archivos (lab) · 📦 Archivos & Compresión I (lab) · 📦 Archivos & Compresión II (lab) · 🌳 Compartir estructuras con tree (lab)
Valida lo aprendido — tests temáticos de Recursos: 📁 Test: Archivos & Navegación
4. LPI 103.4 — Streams, tuberías y redirecciones
Todo proceso en Linux nace con tres flujos abiertos: entrada estándar (stdin, descriptor 0), salida estándar (stdout, descriptor 1) y salida de error (stderr, descriptor 2). Redirigir es simplemente decirle al shell que conecte esos flujos a un fichero o a otro proceso en vez de a la terminal.
| Operador | Qué hace |
|---|---|
> | Redirige stdout a un fichero, sobrescribiéndolo |
>> | Redirige stdout añadiendo al final del fichero |
< | Usa un fichero como entrada estándar de un comando |
2> | Redirige solo stderr a un fichero |
2>&1 | Redirige stderr al mismo sitio donde va stdout en ese momento |
>fichero 2>&1 | Combina ambos flujos en el mismo fichero (el orden importa) |
&>fichero | Atajo de bash para lo anterior |
| | Tubería: conecta la stdout de un comando con la stdin del siguiente |
tee fichero | Divide un flujo: lo escribe en un fichero y lo deja pasar a la salida estándar |
xargs | Convierte la entrada estándar en argumentos de otro comando — imprescindible cuando un comando no acepta entrada por stdin directamente |
$ ls /no/existe > salida.txt 2> error.txt$ cat error.txt
ls: cannot access '/no/existe': No such file or directory$ find / -name '*.conf' 2>/dev/null | wc -l
2142>/dev/null es el patrón más repetido del examen y de la vida real: descarta los errores (típicamente "permiso denegado" al recorrer todo el disco con find) sin perder la salida que sí te interesa.$ dmesg | tee dmesg_copia.txt | grep -i error
[ 12.441023] usb 1-1: error -71$ find . -name '*.tmp' | xargs rm -v
removed './cache/a.tmp'
removed './cache/b.tmp'comando > fichero 2>&1: primero stdout apunta a fichero, y luego stderr se redirige a donde apunta stdout en ese instante — es decir, también a fichero. Si lo escribes al revés (2>&1 > fichero), stderr se queda apuntando a la terminal porque en ese momento stdout todavía no se había movido.5. LPI 103.5 — Crear, vigilar y matar procesos
| Comando | Qué hace |
|---|---|
ps | Foto fija de los procesos en ejecución (ps aux o ps -ef, las dos formas clásicas, una de estilo BSD y otra de estilo Unix) |
top / htop | Vista en vivo, actualizada, ordenable por CPU o memoria |
pgrep patrón | Busca PIDs por nombre de proceso |
pkill patrón | Envía una señal a todos los procesos que coincidan con el patrón |
kill -SEÑAL PID | Envía una señal a un PID concreto |
killall nombre | Como kill, pero por nombre de proceso en vez de PID |
comando & | Lanza el comando en segundo plano |
jobs | Lista los trabajos en segundo/primer plano de la sesión actual |
fg %1 / bg %1 | Trae un trabajo a primer plano / lo reanuda en segundo plano |
Ctrl+Z | Suspende el proceso en primer plano (queda parado, no en segundo plano hasta que haces bg) |
nohup comando & | Lanza un proceso que sobrevive aunque cierres la sesión/terminal |
free -h | Memoria RAM y swap, en formato legible |
uptime | Tiempo encendido y carga media del sistema (load average) |
$ ps aux | grep sshd
root 612 0.0 0.3 14256 6120 ? Ss 10:01 0:00 /usr/sbin/sshd -D$ kill -15 612$ kill -9 612| Señal | Número | Efecto |
|---|---|---|
SIGHUP | 1 | Recarga de configuración en muchos daemons (histórico: "se colgó la línea") |
SIGINT | 2 | Lo que envía Ctrl+C — interrumpir |
SIGKILL | 9 | Mata el proceso de inmediato, sin posibilidad de limpieza — no se puede ignorar ni capturar |
SIGTERM | 15 | Pide al proceso que termine de forma ordenada — la señal por defecto de kill y la que siempre hay que probar primero |
SIGSTOP | 19 | Pausa el proceso — tampoco se puede ignorar |
SIGCONT | 18 | Reanuda un proceso parado |
kill -9: SIGKILL no le da al proceso ninguna oportunidad de cerrar ficheros, liberar locks o guardar estado — puede dejar datos a medio escribir. El orden correcto es: kill (envía SIGTERM por defecto) y solo si el proceso no responde en unos segundos, kill -9 como último recurso.$ sleep 300 &
[1] 4821$ jobs
[1]+ Running sleep 300 &$ fg %1
sleep 300
^Z
[1]+ Stopped sleep 300$ bg %1
[1]+ sleep 300 &Practica más — labs ya publicados en Ghost Academy sobre este tema: ⚙️ Procesos & sistema (lab) · 🔄 Admin de procesos y servicios (lab)
Valida lo aprendido — tests temáticos de Recursos: 🔄 Test: Procesos & Gestión
6. LPI 103.6 — Modificar la prioridad de ejecución
El planificador del kernel reparte CPU entre procesos según su prioridad. En espacio de usuario se controla con el valor nice, que va de -20 (máxima prioridad, el proceso es "menos amable" con los demás) a +19 (mínima prioridad, el proceso cede CPU a todos los demás).
| Comando | Qué hace |
|---|---|
nice -n 10 comando | Lanza un comando nuevo con nice +10 (menor prioridad de la normal) |
renice -n -5 -p PID | Cambia el nice de un proceso ya en marcha |
ps -l | Muestra, entre otras columnas, NI (nice) y PRI (prioridad real que usa el kernel) |
top, tecla r | Cambia el nice de un proceso de forma interactiva, sin salir de top |
$ nice -n 15 tar -czf backup.tar.gz /home/$ renice -n -5 -p 4821
4821 (process ID) old priority 0, new priority -5root puede asignar valores negativos de nice (subir la prioridad) o bajarle la prioridad a un proceso de otro usuario. Un usuario normal solo puede subir el valor nice de sus propios procesos (bajarles prioridad a sí mismo), nunca bajarlo.7. LPI 103.7 — Buscar texto con expresiones regulares
Una expresión regular (regex) describe un patrón de texto, no un texto literal. grep es la herramienta de referencia para buscarlas en ficheros, pero el mismo lenguaje de patrones lo reutilizan sed, awk, vim y prácticamente cualquier lenguaje de programación.
| Metacarácter | Significado |
|---|---|
. | Cualquier carácter individual |
* | Cero o más repeticiones del carácter/grupo anterior |
^ | Principio de línea |
$ | Final de línea |
[abc] | Cualquiera de los caracteres indicados |
[^abc] | Cualquier carácter excepto los indicados |
[0-9], [a-z] | Rangos de caracteres |
\ | Escapa el carácter siguiente (para buscarlo literal, p.ej. \. para un punto literal) |
Estos metacaracteres son regex básica (BRE), la que entiende grep por defecto. La regex extendida (ERE) añade más potencia y la activas con grep -E (o el comando histórico egrep):
| Metacarácter (solo ERE) | Significado |
|---|---|
+ | Una o más repeticiones |
? | Cero o una repetición (opcional) |
{n,m} | Entre n y m repeticiones |
(abc\|xyz) en BRE, (abc|xyz) en ERE | Alternativa: "abc" o "xyz" |
$ grep -E '^[0-9]{3}-[0-9]{4}$' telefonos.txt
555-1234
911-0000$ grep -v '^#' /etc/ssh/sshd_config | grep -v '^$'
Port 22
PermitRootLogin no
PasswordAuthentication no$ grep -ril 'TODO' /var/www/
/var/www/html/index.php
/var/www/html/config.phpOpción de grep | Efecto |
|---|---|
-i | Ignora mayúsculas/minúsculas |
-v | Invierte: muestra las líneas que no coinciden |
-r / -R | Busca recursivamente en subdirectorios |
-l | Muestra solo el nombre de los ficheros con coincidencias, no las líneas |
-n | Muestra el número de línea de cada coincidencia |
-c | Cuenta coincidencias en vez de mostrarlas |
-E | Activa regex extendida (ERE) |
-F (= fgrep) | Trata el patrón como texto literal, sin metacaracteres — más rápido si no necesitas regex |
\+, \?, \| y \{n,m\} para que funcionen como especiales; en ERE (grep -E) esos mismos caracteres ya son especiales sin escapar, y tendrías que escaparlos si los quisieras literales.8. LPI 103.8 — Edición básica de ficheros con vi
vi (o su versión mejorada, vim) está presente en absolutamente todas las instalaciones mínimas de Linux/Unix — por eso el examen lo exige aunque tú uses nano en el día a día. Tres modos, nunca te pierdas entre ellos:
| Modo | Para qué | Cómo se entra |
|---|---|---|
| Normal (comando) | Moverte, borrar, copiar, pegar — el modo por defecto al abrir | Esc desde cualquier otro modo |
| Inserción | Escribir texto literalmente | i (antes del cursor), a (después), o (línea nueva debajo) |
| Línea de comandos (ex) | Guardar, salir, buscar/reemplazar, ejecutar comandos de edición | : desde modo normal |
$ vi /etc/hosts
# abre el fichero en modo normal| Comando (modo normal) | Efecto |
|---|---|
h j k l | Izquierda / abajo / arriba / derecha (las flechas también funcionan) |
dd | Borra (y copia) la línea completa |
yy | Copia ("yank") la línea sin borrarla |
p | Pega después de la línea/posición actual |
u | Deshacer |
Ctrl+R | Rehacer |
x | Borra el carácter bajo el cursor |
/patrón + Enter | Busca hacia adelante; n repite la búsqueda, N en sentido contrario |
G / gg | Ir al final / al principio del fichero |
:5 | Ir directamente a la línea 5 |
Comando (modo ex, tras :) | Efecto |
|---|---|
:w | Guarda |
:q | Sale (falla si hay cambios sin guardar) |
:q! | Sale descartando cambios sin guardar |
:wq (= ZZ en modo normal) | Guarda y sale |
:%s/viejo/nuevo/g | Sustituye "viejo" por "nuevo" en todo el fichero (% = todas las líneas, g = todas las coincidencias por línea) |
:set nu | Muestra números de línea |
vi: escribir texto a pelo sin haber pulsado i antes, y que cada letra ejecute un comando distinto. Si eso pasa y el fichero queda hecho un desastre: Esc para volver a modo normal, y :q! para salir sin guardar nada — vuelves a empezar limpio.$ :%s/127.0.0.1/192.168.1.10/g
# sustituye todas las apariciones en el fichero abiertoPráctica guiada
- Encadena
ps aux,grep,awkysortpara listar los 5 procesos que más memoria consumen ahora mismo en tu VM. - Crea un fichero de prueba con
nl /etc/services | head -20 > /tmp/prueba.txt, ábrelo convi, borra tres líneas conddtres veces, guarda y sal con:wq. - Lanza
sleep 200 &, compruébalo conjobs, tráelo a primer plano confg, suspéndelo conCtrl+Zy reanúdalo en segundo plano conbg. - Busca con
find /etc -name '*.conf' 2>/dev/nully cuenta el resultado conwc -l. - Escribe una expresión regular extendida que capture direcciones IPv4 en un fichero de log cualquiera (
grep -E). - Empaqueta tu propio
/etccontar -czvf etc_backup.tar.gz /etc 2>/dev/nully verifica el contenido contar -tzvf etc_backup.tar.gz | head, sin extraerlo.
Resumen de comandos del módulo
| Bloque | Comandos clave |
|---|---|
| 103.1 Línea de comandos | env, export, history, man, which, type, alias |
| 103.2 Filtros de texto | cut, sort, uniq, tr, sed, awk, wc |
| 103.3 Ficheros | cp, mv, rm, find, file, tar |
| 103.4 Redirecciones | >, >>, 2>&1, |, tee, xargs |
| 103.5 Procesos | ps, top, kill, jobs, fg/bg, nohup |
| 103.6 Prioridades | nice, renice |
| 103.7 Regex | grep, grep -E |
| 103.8 vi | i/Esc, dd/yy/p, :wq/:q!, :%s///g |
Practica más — labs ya publicados en Ghost Academy sobre este tema: 🐧 Comandos Linux (lab) · 📋 Linux Cheatsheet
Valida lo aprendido — tests temáticos de Recursos: 🔧 Test: Varios I · 🔧 Test: Varios II
Autoevaluación
- ¿Qué diferencia hay entre
whichytypea la hora de localizar un comando? - Tienes un fichero de log y quieres las 5 IPs que más veces aparecen. ¿Qué cadena de comandos encadenarías?
- ¿Por qué
uniqcasi siempre va justo después desorten una tubería? - ¿Qué hace exactamente
2>&1, y por qué el orden respecto a>ficheroimporta? - ¿Por qué
kill -9no debería ser tu primera opción para terminar un proceso? - ¿Qué usuario puede bajar el valor nice (subir la prioridad) de un proceso, y por qué un usuario normal no puede?
- Escribe, en regex extendida, un patrón que capture una dirección de correo simple (usuario@dominio.tld).
- Abres un fichero con
viy, sin querer, empiezas a escribir en modo normal, dejándolo hecho un lío. ¿Qué dos pasos te devuelven al fichero original sin guardar nada?