Tienes el snapshot hecho y la sesión abierta en srv-tramontana. Delante tienes un prompt parpadeando y poco más. Esa pantalla, que a primera vista parece una limitación, es en realidad la interfaz más potente que tiene el sistema: todo lo que puede hacerse en un servidor Linux puede hacerse desde ahí, y casi nada de lo que se hace ahí es irrepetible.

Esta lección no es un listado de comandos. Es la lección donde aprendes cómo funciona el intérprete que hay entre tus dedos y el kernel: cómo lee lo que escribes, cómo decide qué programa ejecutar, cómo puedes escribir tres veces más rápido usando el teclado bien, y cómo encadenar órdenes para que una dependa del resultado de la anterior. A partir de aquí, cada comando nuevo que aprendas se apoyará en esta mecánica.

Al terminar deberías poder sentarte en cualquier terminal Linux y moverte sin fricción: sin borrar una línea entera a base de retroceso, sin volver a teclear un comando que ya ejecutaste hace diez minutos, y sin que un espacio en un nombre de archivo te arruine la orden.

Contenido

  1. Por qué la línea de comandos sigue siendo la herramienta profesional
  2. El ciclo REPL: qué hace el shell con lo que escribes
  3. Anatomía de un comando: orden, opciones y argumentos
  4. Comandos internos y externos: builtins, type, which y command -v
  5. Cómo encuentra el shell un ejecutable
  6. Autocompletado con Tab
  7. El historial de órdenes
  8. Editar la línea de órdenes sin sufrir
  9. Encadenar comandos: ;, &&, || y agrupación
  10. Ejecutar en segundo plano con &
  11. Comillas y escapado: cuando el nombre tiene espacios
  12. Cancelar y salir

  1. Por qué la línea de comandos sigue siendo la herramienta profesional

La pregunta es legítima: en 2026, con interfaces gráficas maduras y paneles web de administración, ¿por qué un profesional trabaja en una terminal?

La respuesta no es nostalgia. Son cuatro propiedades que la interfaz gráfica no puede ofrecer:

  • Reproducibilidad. Un comando es texto. Se copia, se pega, se guarda en un documento, se revisa en una revisión de código y se ejecuta idéntico dentro de seis meses. «Haz clic en Configuración, luego en la pestaña Avanzado, luego marca la tercera casilla» no es reproducible: depende de la versión, del idioma y de que la casilla siga ahí.
  • Automatización. Lo que escribes a mano hoy es literalmente la primera línea del script que lo hará solo mañana. Entre ejecutar un comando y automatizarlo no hay traducción: es el mismo texto. En una interfaz gráfica, automatizar significa reescribir todo el proceso en otro lenguaje.
  • Trabajo remoto. srv-tramontana no tiene monitor ni lo tendrá. Cuando el servidor esté en un centro de datos o en una nube, tu única puerta será SSH. La CLI está diseñada para eso; el escritorio remoto es un parche.
  • Coste en recursos y ancho de banda. Una sesión SSH consume unos pocos kilobytes por minuto y funciona sobre una conexión móvil mala desde un tren. Un escritorio remoto necesita megabits y se cae. Cuando tengas una incidencia a las tres de la mañana desde el móvil, esto dejará de ser un detalle técnico.

Ahora la parte honesta, porque la CLI no gana en todo:

Criterio Interfaz gráfica (GUI) Línea de comandos (CLI)
Curva de aprendizaje Suave: las opciones se ven Pronunciada: hay que saber que existen
Descubribilidad Alta: exploras menús Baja: necesitas documentación (lección 02-02)
Velocidad al experto Limitada por el ratón Muy alta
Reproducibilidad Baja Total
Automatización Difícil o imposible Nativa
Trabajo remoto Pesado, frágil Ligero, robusto
Tareas visuales (imágenes, diseño, diagramas) Insustituible Inadecuada
Consumo de recursos Alto Mínimo
Margen de error destructivo Bajo: confirma y avisa Alto: ejecuta y calla

Ese último punto merece que te detengas. La filosofía Unix que viste en el Módulo 1 incluye una regla implícita: el silencio es señal de éxito. Si un comando funciona, normalmente no dice nada. Y si le pides que borre un árbol de directorios, lo borra sin preguntar. La potencia y el peligro son la misma propiedad vista desde dos lados.

La conclusión profesional no es «la CLI es mejor», sino: para administrar sistemas, la CLI es la herramienta correcta, y no dominarla te limita a hacer a mano lo que otros automatizan.

  1. El ciclo REPL: qué hace el shell con lo que escribes

Bash no ejecuta lo que escribes. Ejecuta el resultado de procesar lo que escribes. Entender esa diferencia te ahorrará muchas sorpresas.

El shell funciona en un bucle llamado REPL (Read–Eval–Print–Loop): lee, evalúa, muestra y vuelve a empezar.

flowchart TD
    A[Muestra el prompt] --> B[LEER: espera una línea completa]
    B --> C[TROCEAR: divide en palabras por espacios]
    C --> D[EXPANDIR: comodines, variables, sustituciones, ~]
    D --> E[RESOLVER: ¿es builtin, alias o programa externo?]
    E --> F[EJECUTAR: lanza el proceso y espera]
    F --> G[MOSTRAR: salida estándar y errores en pantalla]
    G --> H[GUARDAR: código de salida en $? e historial]
    H --> A

Fíjate en el paso EXPANDIR: ocurre antes de ejecutar nada. Cuando escribes un comando con un *, el programa nunca ve el asterisco; ve la lista de nombres que el shell ha puesto en su lugar. Los comodines y las variables se estudian en el Módulo 3, pero conviene que sepas ya que existe esa fase intermedia, porque explica comportamientos que de otro modo parecen mágicos.

Y fíjate en TROCEAR: el shell divide la línea por espacios antes de saber qué significan. Ese detalle es la causa del problema de las comillas que verás en el apartado 11.

  1. Anatomía de un comando: orden, opciones y argumentos

Ya viste la forma general en el Módulo 1. Ahora la desmontamos entera:

comando [opciones] [argumentos]
  • Comando: qué quieres hacer. Siempre la primera palabra.
  • Opciones (o flags, modificadores): cómo quieres hacerlo. Empiezan por - o --.
  • Argumentos (u operandos): sobre qué quieres hacerlo. Normalmente archivos o rutas.
operador@srv-tramontana:~$ ls -l -h /var/log/tramontana
total 32K
-rw-r----- 1 root adm  18K ago 18 09:14 acceso.log
-rw-r----- 1 root adm 6,2K ago 18 09:02 errores.log

Aquí ls es el comando, -l y -h son opciones y /var/log/tramontana es el argumento. Sin argumento, ls usa un valor por defecto (el directorio actual); sin opciones, usa su comportamiento por defecto.

Opciones cortas, largas y con valor

Forma Ejemplo Notas
Corta -l Una letra, un guion. Distingue mayúsculas: -r y -R suelen ser cosas distintas
Cortas agrupadas -lh = -l -h Solo se agrupan las que no llevan valor
Larga --human-readable Dos guiones, palabra completa. Más legible en scripts
Corta con valor -n 5 o -n5 El espacio suele ser opcional, pero no siempre
Larga con valor --lines=5 o --lines 5 Con = es la forma más segura

Las tres invocaciones siguientes son equivalentes:

ls -l -a -h /etc
ls -lah /etc
ls --format=long --all --human-readable /etc

Criterio profesional: usa cortas cuando escribes a mano (rapidez) y largas cuando escribes un script o documentas un procedimiento (legibilidad). Dentro de seis meses, --human-readable se entiende solo; -h obliga a mirar el manual. Y ojo: -h no significa lo mismo en todos los comandos.

El separador --

-- a secas significa «se acabaron las opciones; todo lo que venga después es un argumento, aunque empiece por guion».

operador@srv-tramontana:~$ touch -- -informe.txt
operador@srv-tramontana:~$ ls
-informe.txt

operador@srv-tramontana:~$ rm -informe.txt
rm: opción inválida -- 'i'
Pruebe 'rm ./-informe.txt' para eliminar el fichero '-informe.txt'.

operador@srv-tramontana:~$ rm -- -informe.txt

Sin --, rm interpreta -informe.txt como un montón de opciones sueltas. Es un caso raro escribiendo a mano, pero deja de serlo cuando un script recibe nombres de archivo de fuera: cualquier nombre que empiece por guion puede alterar el comportamiento del comando. Por eso los scripts serios (Módulo 4) usan -- antes de los datos.

  1. Comandos internos y externos: builtins, type, which y command -v

No todos los comandos son programas. Hay dos categorías:

  • Builtins (internos): los implementa Bash. No hay ningún archivo que ejecutar; el shell hace el trabajo él mismo. Son rapidísimos.
  • Externos: son ejecutables en disco (/bin/ls, /usr/bin/find...). El shell crea un proceso nuevo para ejecutarlos.

La herramienta para distinguirlos es type:

operador@srv-tramontana:~$ type cd
cd es una orden interna del shell

operador@srv-tramontana:~$ type ls
ls es un alias de «ls --color=auto»

operador@srv-tramontana:~$ type -a ls
ls es un alias de «ls --color=auto»
ls es /usr/bin/ls

operador@srv-tramontana:~$ type grep
grep es /usr/bin/grep

type -a muestra todas las resoluciones posibles, en orden de prioridad. Es la herramienta de diagnóstico cuando un comando «no hace lo que debería»: casi siempre hay un alias o un script por delante del programa real.

Herramienta Qué hace Cuándo usarla
type <cmd> Dice qué es: builtin, alias, función o archivo Diagnóstico. La más completa
type -a <cmd> Todas las resoluciones, por prioridad Cuando sospechas de un alias o duplicado
which <cmd> Ruta del ejecutable externo Rápido, pero ignora builtins y aliases
command -v <cmd> Resolución en una línea En scripts: es POSIX y portable
operador@srv-tramontana:~$ which cd
operador@srv-tramontana:~$ echo $?
1

which cd no devuelve nada y falla, porque cd no es un archivo. Esa es exactamente la limitación por la que which no sirve como herramienta de diagnóstico general.

Por qué cd tiene que ser builtin

Esta pregunta aparece en las entrevistas técnicas, y su respuesta explica algo real sobre cómo funciona el sistema.

Cada proceso en Linux tiene su propio directorio de trabajo, que es un atributo privado del proceso. Cuando ejecutas un programa externo, el shell crea un proceso hijo y ese hijo hereda una copia del entorno del padre. El hijo puede cambiar lo que quiera de su copia: cuando termina, su copia desaparece y el padre sigue exactamente igual.

flowchart LR
    A[Bash<br/>cwd = /home/operador] -->|crea hijo| B[Proceso hijo<br/>cwd = /home/operador]
    B -->|cambia su cwd| C[Proceso hijo<br/>cwd = /etc]
    C -->|termina| D[Bash<br/>cwd = /home/operador<br/>SIN CAMBIOS]

Si cd fuera un programa externo, cambiaría el directorio de su propio proceso y moriría inmediatamente. Tu shell no se movería nunca. Por eso cd tiene que ejecutarse dentro del propio proceso del shell, es decir, ser un builtin.

La misma lógica se aplica a export, alias, source, exit, umask o history: todo lo que modifica el estado del shell debe ser interno. Guárdate esta idea, porque es la que explica por qué un script no puede cambiar el directorio de quien lo llama (Módulo 4).

  1. Cómo encuentra el shell un ejecutable

Cuando escribes grep, el shell no rastrea el disco. Sigue un orden estricto:

  1. ¿Es un alias? Lo sustituye.
  2. ¿Es una función de shell? La ejecuta.
  3. ¿Es un builtin? Lo ejecuta.
  4. Si no, busca un archivo ejecutable con ese nombre en los directorios listados en la variable PATH, en orden, y usa el primero que encuentre.
  5. Si no lo encuentra: orden no encontrada.
operador@srv-tramontana:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Son directorios separados por :. Es una lista de sitios donde mirar, no una búsqueda por todo el disco. Dos consecuencias prácticas:

  • Un programa que está en un directorio fuera del PATH no se ejecuta escribiendo su nombre. Hay que dar su ruta: por eso tus scripts en /home/operador/scripts se lanzarán como ./informe.sh o con la ruta completa.
  • El orden importa. Si hubiera dos ejecutables con el mismo nombre en dos directorios del PATH, gana el que aparezca antes.

El directorio actual no está en el PATH, y eso es una decisión de seguridad deliberada: si lo estuviera, dejar un archivo llamado ls en un directorio compartido bastaría para engañar a quien entrara ahí. Nunca añadas . al PATH.

El detalle completo de PATH (cómo se modifica, dónde se define y qué es exactamente una variable de entorno) es materia de la lección 03-01. Aquí te basta el concepto.

  1. Autocompletado con Tab

El tabulador es la tecla que más va a mejorar tu velocidad, y no solo por ahorrar pulsaciones: completar con Tab evita erratas. Si el nombre se completa solo, existe.

Reglas de funcionamiento:

  • Una pulsación con una única coincidencia: completa el resto.
  • Una pulsación con varias coincidencias: completa la parte común y se queda ahí (y suele emitir un pitido).
  • Dos pulsaciones: muestra la lista de todas las coincidencias.
operador@srv-tramontana:~$ cd /var/log/tram<Tab>
operador@srv-tramontana:~$ cd /var/log/tramontana/

operador@srv-tramontana:~$ ls /var/log/tramontana/<Tab><Tab>
acceso.log   errores.log

operador@srv-tramontana:~$ ls /var/log/tramontana/a<Tab>
operador@srv-tramontana:~$ ls /var/log/tramontana/acceso.log

Qué completa según la posición en la línea:

Posición Qué ofrece
Primera palabra Comandos, builtins, aliases y funciones
Después de un comando Archivos y directorios
Tras ~ Nombres de usuario: ~ope<Tab> → ~operador/
Tras $ Nombres de variables
Tras - o -- Opciones del comando (si hay completado instalado)

Esa última fila depende del paquete bash-completion, presente por defecto en Ubuntu Server 24.04. Gracias a él, muchos comandos completan sus propias opciones y hasta sus argumentos:

operador@srv-tramontana:~$ systemctl --stat<Tab>
operador@srv-tramontana:~$ systemctl --state=

Consejo de higiene: si escribes un nombre largo entero y sin Tab, y luego falla, has perdido el tiempo dos veces. Escribe tres letras y pulsa Tab. Si no completa, es que el archivo no está donde crees, y acabas de descubrir el error antes de ejecutar nada.

  1. El historial de órdenes

Bash guarda lo que ejecutas en memoria durante la sesión y lo vuelca al archivo ~/.bash_history al salir. Eso te permite no reescribir nunca lo mismo dos veces.

operador@srv-tramontana:~$ history
  ...
  147  df -h
  148  ls -l /var/log/tramontana
  149  uptime
  150  history

operador@srv-tramontana:~$ history 3
  149  uptime
  150  history
  151  history 3

Formas de reutilizar el historial:

Atajo Qué hace
Flecha arriba / abajo Recorre el historial hacia atrás y hacia delante
Ctrl+R Búsqueda incremental hacia atrás: escribe un fragmento y aparece el comando
Ctrl+R repetido Salta a la coincidencia anterior
Ctrl+G o Ctrl+C Cancela la búsqueda y deja la línea como estaba
!! El último comando entero
!148 El comando número 148 del historial
!ls El último comando que empezaba por ls
!$ El último argumento del comando anterior
!* Todos los argumentos del comando anterior

Ctrl+R es, con diferencia, el atajo más rentable del apartado. Pulsa Ctrl+R, escribe tram y Bash te va mostrando el comando más reciente que contenga esa cadena. Pulsa Enter para ejecutarlo o flecha derecha para editarlo antes.

Los dos idiomas más útiles del día a día son !! y !$:

operador@srv-tramontana:~$ cat /etc/tramontana/app.conf
cat: /etc/tramontana/app.conf: Permiso denegado

operador@srv-tramontana:~$ sudo !!
sudo cat /etc/tramontana/app.conf
[sudo] contraseña para operador:
# Configuración de Tramontana Reservas
db_host=127.0.0.1
...

sudo !! reejecuta el comando anterior con privilegios. Bash muestra la línea expandida antes de ejecutarla, lo que te da la oportunidad de ver qué va a pasar.

operador@srv-tramontana:~$ ls -l /var/log/tramontana/acceso.log
-rw-r----- 1 root adm 18432 ago 18 09:14 /var/log/tramontana/acceso.log

operador@srv-tramontana:~$ sudo tail -n 3 !$
sudo tail -n 3 /var/log/tramontana/acceso.log
2026-08-18 09:14:02 GET /reservas 200 usuario=mvidal
2026-08-18 09:14:07 POST /reservas 201 casa=mas-figueres
2026-08-18 09:14:11 GET /casas 200 usuario=anon

!$ recupera el último argumento: patrón clásico de «primero miro, luego actúo» sin volver a escribir la ruta.

Una advertencia de seguridad que conviene interiorizar ya: el historial es un archivo de texto plano. Si escribes una contraseña como argumento de un comando, queda guardada en ~/.bash_history. Nunca pases secretos por la línea de órdenes; la gestión correcta de credenciales se trata en la lección 06-05.

  1. Editar la línea de órdenes sin sufrir

Bash usa la librería readline, que trae los atajos de edición del editor Emacs. Los mismos atajos funcionan en muchos otros programas de terminal, así que aprenderlos rinde más allá del shell.

Atajo Acción
Ctrl+A Ir al principio de la línea
Ctrl+E Ir al final de la línea
Alt+B Retroceder una palabra
Alt+F Avanzar una palabra
Ctrl+W Borrar la palabra anterior al cursor
Ctrl+U Borrar desde el cursor hasta el principio
Ctrl+K Borrar desde el cursor hasta el final
Ctrl+Y Pegar lo último que borraste con W, U o K
Alt+D Borrar la palabra siguiente
Ctrl+T Intercambiar los dos caracteres alrededor del cursor
Ctrl+_ Deshacer la última edición
Ctrl+L Limpiar la pantalla (conserva la línea)

Regla mnemotécnica: A de anfang o «principio del abecedario», E de end, K de kill hasta el final, U de undo hasta el principio, W de word.

El caso práctico más frecuente: escribes una orden larga, ves una errata al principio y estás en el final. En vez de mantener pulsado el retroceso, Ctrl+A, corriges, Ctrl+E, Enter. Y si la línea entera está mal: Ctrl+U la borra de golpe.

Detalle útil: en muchos emuladores de terminal, Alt funciona directamente; si no, la alternativa es pulsar Esc y soltar antes de la letra (Esc luego B equivale a Alt+B).

  1. Encadenar comandos: ;, &&, || y agrupación

Puedes poner varias órdenes en una sola línea, y la diferencia entre los separadores no es cosmética: es lógica de control.

Para entenderla necesitas el código de salida: todo comando, al terminar, devuelve un número. 0 significa éxito; cualquier otro valor significa fallo. Lo consultas con $? (lo desarrollaremos en la lección 02-02).

Operador Nombre Comportamiento
; Secuencia Ejecuta el siguiente siempre, pase lo que pase
&& Y lógico Ejecuta el siguiente solo si el anterior tuvo éxito (código 0)
|| O lógico Ejecuta el siguiente solo si el anterior falló (código ≠ 0)
operador@srv-tramontana:~$ cd /directorio/que/no/existe ; echo "sigo aquí"
-bash: cd: /directorio/que/no/existe: No existe el fichero o el directorio
sigo aquí

operador@srv-tramontana:~$ cd /directorio/que/no/existe && echo "sigo aquí"
-bash: cd: /directorio/que/no/existe: No existe el fichero o el directorio

operador@srv-tramontana:~$ cd /directorio/que/no/existe || echo "no pude entrar"
-bash: cd: /directorio/que/no/existe: No existe el fichero o el directorio
no pude entrar

La diferencia es crítica en la práctica. Compara estas dos líneas:

cd /srv/tramontana/backups ; rm -r antiguos
cd /srv/tramontana/backups && rm -r antiguos

Si el directorio no existe, la primera cambia de opinión pero no de intención: no entra, y borra antiguos en el directorio en el que estuvieras, que puede ser tu home. La segunda no hace nada. Regla que debes adoptar desde hoy: cuando una orden dependa de que la anterior haya funcionado, usa &&, nunca ;.

Se pueden combinar los tres, y también agrupar con paréntesis:

operador@srv-tramontana:~$ ls /opt/tramontana/app && echo "OK: la app está" || echo "AVISO: falta la app"
ejecutable  plantillas  version.txt
OK: la app está

Los paréntesis agrupan órdenes en un subshell: un proceso hijo con su propio directorio de trabajo y su propio estado.

operador@srv-tramontana:~$ pwd
/home/operador
operador@srv-tramontana:~$ (cd /var/log/tramontana && ls)
acceso.log  errores.log
operador@srv-tramontana:~$ pwd
/home/operador

El cd dentro de los paréntesis afectó solo al subshell; al volver, sigues donde estabas. Es exactamente el mecanismo del apartado 4, ahora usado a tu favor: entra, haz algo, y que el cd no te contamine la sesión.

Con llaves { ...; } se agrupa sin crear subshell (los cambios sí afectan a tu sesión). Es una distinción que retomaremos al escribir scripts en el Módulo 4.

  1. Ejecutar en segundo plano con &

Un & al final de una orden la lanza en segundo plano: el shell no espera a que termine y te devuelve el prompt inmediatamente.

operador@srv-tramontana:~$ sleep 60 &
[1] 4127
operador@srv-tramontana:~$ jobs
[1]+  Ejecutando              sleep 60 &
operador@srv-tramontana:~$ fg %1
sleep 60
  • [1] es el número de trabajo dentro de esta sesión; 4127 es el PID del proceso en el sistema.
  • jobs lista los trabajos de la sesión, fg trae uno al primer plano y bg reanuda en segundo plano uno detenido.
  • Ctrl+Z detiene (no mata) el proceso en primer plano y te devuelve el prompt.

Estas son solo las nociones para que reconozcas la sintaxis. El control de trabajos completo, los procesos, las señales y qué pasa con un proceso en segundo plano cuando cierras la sesión son materia de la lección 03-06.

  1. Comillas y escapado: cuando el nombre tiene espacios

Vuelve al ciclo REPL del apartado 2: el shell trocea la línea por espacios antes de ejecutar nada. Ahí está la explicación de un error clásico:

operador@srv-tramontana:~$ ls
informe agosto.txt  reservas.csv

operador@srv-tramontana:~$ rm informe agosto.txt
rm: no se puede borrar 'informe': No existe el fichero o el directorio
rm: no se puede borrar 'agosto.txt': No existe el fichero o el directorio

rm nunca vio un nombre con espacio: recibió dos argumentos, informe y agosto.txt. El shell hizo su trabajo; el problema es que no le dijiste que el espacio formaba parte del nombre.

Tres formas de arreglarlo:

rm 'informe agosto.txt'      # comillas simples
rm "informe agosto.txt"      # comillas dobles
rm informe\ agosto.txt       # barra invertida escapando el espacio

Y la cuarta, la que usarás de verdad: escribe inf y pulsa Tab. Bash completa el nombre y escapa el espacio por ti.

Diferencia entre los tres mecanismos:

Mecanismo Qué protege Qué sigue interpretándose
'comillas simples' Todo, literalmente Nada. Ni siquiera se puede meter una comilla simple dentro
"comillas dobles" Espacios y comodines $variable, `orden`, $(orden) y \
\ (barra invertida) El carácter siguiente El resto de la línea
operador@srv-tramontana:~$ echo 'El usuario es $USER'
El usuario es $USER
operador@srv-tramontana:~$ echo "El usuario es $USER"
El usuario es operador

La regla práctica hasta el Módulo 3 es sencilla: si quieres el texto tal cual, comillas simples; si esperas que algo dentro se sustituya, comillas dobles. Por qué se sustituye y qué más se puede sustituir es el contenido de la lección 03-01.

Un apunte de estilo aplicable a srv-tramontana: no pongas espacios en los nombres de archivo de un servidor. Usa guiones o guiones bajos (informe-agosto.txt). No es una manía: cada espacio es una trampa esperando a que alguien escriba un script sin comillas.

  1. Cancelar y salir

Tres teclas que hay que distinguir bien porque se confunden a menudo:

Combinación Qué hace Cuándo usarla
Ctrl+C Envía la señal de interrupción al programa en primer plano Un comando se ha quedado colgado o tarda demasiado
Ctrl+D Envía fin de entrada (EOF) Terminar de escribir datos; con la línea vacía, cierra la sesión
exit Termina el shell explícitamente Cerrar la sesión de forma clara, sobre todo en SSH
Ctrl+Z Detiene (no mata) el proceso y lo deja en segundo plano Aparcar algo un momento; se retoma con fg

La diferencia entre Ctrl+C y Ctrl+D importa: Ctrl+C interrumpe, Ctrl+D dice que no hay más datos. Si un comando parece colgado sin hacer nada, muchas veces está esperando que escribas algo por teclado y la salida correcta es Ctrl+D, no Ctrl+C.

Y Ctrl+Z no mata nada, solo lo suspende. Es un error frecuente creer que has cerrado un editor con Ctrl+Z cuando en realidad lo has dejado detenido en segundo plano, bloqueando el archivo.

Errores Comunes y Consejos

Usar ; donde tocaba &&. Es el error de este capítulo con consecuencias más graves, porque solo se manifiesta cuando algo falla, es decir, en el peor momento. Cadena con && por defecto.

Escribir rutas largas a mano. Cada carácter tecleado es una oportunidad de errata. Tab siempre.

Confiar en which para diagnosticar. No ve builtins ni aliases. Si algo se comporta raro, type -a es la respuesta.

Olvidar que Linux distingue mayúsculas. Reservas.csv y reservas.csv son dos archivos distintos. Viniendo de Windows, esto muerde durante las primeras semanas.

Espacios sin proteger. Si un nombre tiene espacios y no lo entrecomillas, el shell verá varios argumentos. Y si el comando era rm, borrará cosas que no querías.

Copiar comandos de internet sin leerlos. Especialmente los que empiezan por sudo o contienen rm -rf. Antes de ejecutar algo que no entiendes, léelo entero y, si hace falta, consúltalo en el manual (lección 02-02).

Consejo: escribe primero el comando inofensivo. ¿Vas a borrar con un patrón? Ejecuta antes ls con el mismo patrón y mira qué sale. Luego pulsa flecha arriba, cambia ls por rm y ejecuta. Es la costumbre que separa a quien ha perdido datos de quien no.

Consejo: pon una línea larga en varias. Una barra invertida al final de la línea permite continuar en la siguiente, y hace las órdenes complejas mucho más legibles cuando las pegas en documentación.

Consejo: Ctrl+L en vez de clear. Es más rápido y no pierdes la línea que estuvieras escribiendo.

Ejercicios

Ejercicio 1: reconocimiento del shell

En srv-tramontana, responde con comandos (no de memoria):

  1. ¿echo es un builtin, un programa externo, o ambos?
  2. ¿Cuántos directorios hay en tu PATH?
  3. ¿Tiene ls algún alias definido? ¿Cuál?
  4. ¿Por qué which cd no devuelve nada?

Ejercicio 2: la trampa de Luis

Luis Ferrer te pasa por chat esta línea para limpiar los volcados temporales de la aplicación, diciendo que «la ha probado en su portátil y va bien»:

cd /srv/tramontana/backups/temporales ; rm -r *

Explica qué puede salir mal, reescríbela de forma segura y añade una comprobación previa que te enseñe qué se va a borrar antes de borrarlo.

Ejercicio 3: velocidad de teclado

Sin usar el ratón y sin borrar carácter a carácter:

  1. Escribe ls -l /var/log/tramontana/acceso.log y ejecútalo.
  2. Ejecuta ahora wc -l sobre ese mismo archivo sin volver a teclear la ruta.
  3. Recupera del historial el primer comando y modifícalo para que muestre errores.log en vez de acceso.log, usando solo atajos de edición.
  4. Crea un archivo llamado informe marta.txt, comprueba que existe y bórralo. Explica por qué el nombre es una mala idea en un servidor.

Soluciones

Solución 1

operador@srv-tramontana:~$ type -a echo
echo es una orden interna del shell
echo es /usr/bin/echo

Ambos. Bash tiene su propio echo builtin y además existe /usr/bin/echo. Gana el builtin, porque los internos tienen prioridad sobre el PATH. Es un caso frecuente: echo, test, kill o printf existen en las dos formas, y sus opciones no siempre coinciden entre ellas, lo que explica algunos comportamientos desconcertantes en scripts portados de un sistema a otro.

operador@srv-tramontana:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Seis directorios, separados por :. Puedes contarlos a ojo; en el Módulo 3 verás cómo hacerlo con un comando.

operador@srv-tramontana:~$ type ls
ls es un alias de «ls --color=auto»

Sí: Ubuntu define ls --color=auto en el ~/.bashrc. Por eso los directorios te salen en azul: no es ls haciéndolo por su cuenta, es el alias. Los aliases se estudian en 03-01.

which cd no devuelve nada porque cd no es un archivo en disco: es un builtin. Y tiene que serlo porque debe cambiar el directorio de trabajo del propio proceso del shell, algo que un proceso hijo no puede hacer sobre su padre.

Solución 2

Qué puede salir mal. El punto y coma ejecuta rm -r * pase lo que pase con el cd. Si /srv/tramontana/backups/temporales no existe, está mal escrito, o el directorio ha sido renombrado, cd falla y rm -r * se ejecuta en el directorio actual. Si en ese momento estabas en /home/operador, acabas de borrar tu home, incluido /home/operador/scripts. Si estabas en /opt/tramontana, te has llevado la aplicación por delante.

Que «funcione en el portátil de Luis» es precisamente la señal de alarma: funciona mientras el directorio exista. El fallo aparece el día que no existe, que es el día en que nadie está mirando.

Versión segura:

# 1. Primero mirar, sin tocar nada
operador@srv-tramontana:~$ ls -la /srv/tramontana/backups/temporales
total 12
drwxr-x--- 2 operador operador 4096 ago 18 08:30 .
drwxr-x--- 3 operador operador 4096 ago 18 08:30 ..
-rw-r----- 1 operador operador  842 ago 17 23:00 volcado-2026-08-17.tmp

# 2. Encadenar con && y usar -I, que pide UNA confirmación si son muchos archivos
operador@srv-tramontana:~$ cd /srv/tramontana/backups/temporales && rm -rI ./*

Mejoras aplicadas:

  • && en lugar de ;: si el cd falla, no se borra nada. Es el cambio importante.
  • ls -la primero: ves exactamente qué hay antes de destruirlo.
  • ./* en lugar de *: protege frente a nombres que empiecen por guion.
  • -I: pide una confirmación única cuando hay más de tres elementos. Menos molesto que -i y suficiente para pararte a pensar.

Alternativa aún mejor, que evita el cd por completo y no deja la sesión en otro directorio:

operador@srv-tramontana:~$ (cd /srv/tramontana/backups/temporales && ls -la && rm -rI ./*)

Cómo se lo dirías a Luis: no que su comando esté mal escrito, sino que le falta la condición. El ; dice «haz esto y luego aquello»; && dice «haz aquello solo si esto salió bien». En una limpieza con rm -r, esa diferencia es la que separa un mantenimiento rutinario de un incidente.

Solución 3

operador@srv-tramontana:~$ ls -l /var/log/tramontana/acceso.log
-rw-r----- 1 root adm 18432 ago 18 09:14 /var/log/tramontana/acceso.log

operador@srv-tramontana:~$ sudo wc -l !$
sudo wc -l /var/log/tramontana/acceso.log
412 /var/log/tramontana/acceso.log

!$ recupera el último argumento del comando anterior. Bash muestra la línea ya expandida antes de ejecutarla, lo que te deja verificar que apunta a donde crees.

Para el punto 3, la secuencia con atajos:

  1. Flecha arriba dos veces (o Ctrl+R y escribir acceso) hasta recuperar ls -l /var/log/tramontana/acceso.log.
  2. Ctrl+W borra la última palabra, que en este caso es la ruta completa hasta el espacio anterior. Como quieres cambiar solo el nombre del archivo, es más limpio: Alt+B para retroceder por palabras hasta situarte sobre acceso, borrar esa palabra con Alt+D y escribir errores.
  3. Enter.
operador@srv-tramontana:~$ ls -l /var/log/tramontana/errores.log
-rw-r----- 1 root adm 6348 ago 18 09:02 /var/log/tramontana/errores.log

Con nombres largos, Ctrl+A para ir al principio y Alt+F para avanzar por palabras suele ser más rápido que mantener pulsada la flecha izquierda.

Para el punto 4:

operador@srv-tramontana:~$ touch 'informe marta.txt'
operador@srv-tramontana:~$ ls -l informe*
-rw-rw-r-- 1 operador operador 0 ago 18 10:22 'informe marta.txt'
operador@srv-tramontana:~$ rm 'informe marta.txt'

Fíjate en que ls de Ubuntu muestra el nombre entre comillas precisamente para avisarte de que contiene un espacio.

Por qué es mala idea en un servidor: el archivo funciona perfectamente mientras lo manejes a mano con Tab, pero el día que aparezca en un script sin comillas se romperá, y lo hará de la peor forma posible: no fallando, sino tratando informe y marta.txt como dos rutas. En un rm, eso es un borrado equivocado; en un bucle de copia, un fichero que no se respalda. La convención profesional es informe-marta.txt o informe_marta.txt.

Conclusión

Ya no estás mirando una pantalla negra: estás manejando un intérprete cuyo funcionamiento entiendes.

  • La CLI es la herramienta profesional por reproducible, automatizable, remota y ligera, no por tradición; y su contrapartida honesta es que no perdona ni avisa.
  • El shell sigue un ciclo REPL en el que expande antes de ejecutar: el programa nunca ve exactamente lo que escribiste.
  • Un comando tiene tres partes, sus opciones pueden ser cortas, agrupadas, largas o con valor, y -- cierra la lista de opciones.
  • Hay builtins y externos; type -a es tu herramienta de diagnóstico, y cd tiene que ser builtin porque ningún hijo puede mover a su padre.
  • El shell localiza los ejecutables recorriendo el PATH en orden, y el directorio actual no está ahí por razones de seguridad.
  • Tab te ahorra pulsaciones y, sobre todo, erratas; Ctrl+R, !! y !$ te ahorran reescribir; los atajos de readline te ahorran el retroceso interminable.
  • ;, && y || son lógica de control, no puntuación: && es tu opción por defecto cuando una orden depende de la anterior.
  • Los espacios en los nombres se protegen con comillas simples, dobles o barra invertida, y lo mejor es no tenerlos.

Con esto puedes escribir órdenes con soltura. Falta el otro pilar de la autosuficiencia: saber qué órdenes existen y qué hace cada opción sin depender de un buscador. En la próxima lección, Obtener Ayuda y Documentación del Sistema, aprenderás a leer una página de man de principio a fin, a entender la notación del SYNOPSIS, a moverte por las ocho secciones del manual, a buscar un comando cuando ni siquiera sabes su nombre, y a resolver una duda real de Luis Ferrer usando únicamente lo que ya está instalado en srv-tramontana. Es la lección que convierte «no sé hacerlo» en «no lo sé todavía».

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados