Módulo 1: La terminal y el sistema de archivos
4. Anatomía de un comando: opciones y argumentos
Descripción
Al terminar esta lección vas a poder mirar cualquier comando —incluso uno que nunca viste antes, copiado de un tutorial, de una respuesta en un foro o sugerido por un modelo de lenguaje— y separarlo en sus tres piezas: qué programa se va a ejecutar, qué modificadores le estás pasando y sobre qué datos va a actuar. Esa separación es lo que te permite predecir qué va a pasar antes de presionar Enter, en lugar de descubrirlo por las malas.
Esto importa en el trabajo real todos los días: vas a copiar comandos de la documentación de una herramienta, de un compañero de equipo o de un script de integración continua, y vas a tener que decidir en segundos si es seguro ejecutarlos tal cual o si necesitas ajustar algo antes. Un comando con rm, con sudo o con una redirección mal entendida puede borrar o sobrescribir lo que no debía. Entender su anatomía es el primer filtro de seguridad — antes incluso de saber leer su manual, que es exactamente el tema de la próxima lección.
Conexión con el módulo: la lección anterior te dejó con una terminal abierta y funcionando en tu sistema operativo. Esta te da la gramática para leer cualquier cosa que escribas en ella. Sin esa gramática, cada comando nuevo es un jeroglífico; con ella, es una oración con una estructura reconocible.
La gramática universal de un comando
Piensa en cómo le darías una instrucción a alguien en una cocina: "corta el pan, finito, con el cuchillo grande". Ahí hay tres piezas distintas de información: la acción (cortar), un modificador de cómo hacer esa acción (finito) y el objeto sobre el que actúa (el pan). Si cambias el modificador — "corta el pan, grueso" — la acción sigue siendo la misma, pero el resultado cambia. Un comando de terminal está armado exactamente igual.
Todo lo que escribes en una terminal sigue esta misma estructura de tres piezas:
- Comando: el nombre del programa que quieres ejecutar (
ls,grep,tar,mkdir…). Siempre va primero. - Opciones (también llamadas flags): modificadores que cambian cómo se comporta ese comando. Siempre empiezan con uno o dos guiones.
- Argumentos: los datos sobre los que el comando va a actuar — casi siempre un archivo, una carpeta o un texto.
El comando siempre va primero. Por convención, después suelen ir las opciones y al final los argumentos, aunque muchos programas modernos toleran mezclar el orden entre opciones y argumentos sin problema.
Ejemplo trabajado
ls -la /etc
Qué esperar (salida real, recortada):
total 1240
drwxr-xr-x 87 root root 8192 Jul 18 09:14 .
drwxr-xr-x 20 root root 4096 Jun 2 08:00 ..
-rw-r--r-- 1 root root 3028 Ene 10 2026 adduser.conf
-rw-r--r-- 1 root root 2761 Mar 5 09:22 bash.bashrc
drwxr-xr-x 3 root root 4096 Jul 18 09:14 cron.d
...
Separando el comando en sus tres piezas:
lses el comando: el programa que buscas ejecutar.-lason opciones combinadas:-lle pide el formato largo (una línea por archivo, con permisos, dueño, tamaño y fecha) y-ale pide que incluya también los archivos ocultos (los que empiezan con.)./etces el argumento: la ruta sobre la quelsdebe operar.
No te preocupes todavía por descifrar cada columna de esa salida — eso es justo lo que cubre la lección de navegación más adelante en este módulo. Por ahora quédate solo con la forma: comando, luego opciones, luego argumento.
Flags cortos y largos: la misma opción, dos formas de escribirla
Casi toda opción común en herramientas de línea de comandos tiene dos formas de escribirse, y ambas hacen exactamente lo mismo:
grep -i "root" /etc/passwd
grep --ignore-case "root" /etc/passwd
- Flag corto: un solo guion seguido de una letra (
-i). Rápido de escribir, pensado para uso interactivo del día a día. - Flag largo: dos guiones seguidos de una palabra completa en inglés (
--ignore-case). Más lento de escribir, pero autodescriptivo — ideal para un script que alguien más (o tú mismo, en seis meses) va a tener que leer sin ejecutarlo.
Nota multiplataforma: en Linux y dentro de WSL —que corre Linux real, como viste en la lección anterior— ls es la versión de GNU coreutils y entiende tanto -a como su forma larga --all. En macOS, en cambio, ls es la versión de BSD y solo entiende las opciones cortas: no existe un --all equivalente. Si copias un tutorial escrito para Linux y algún flag largo te da error en macOS, no es que lo escribiste mal: son dos implementaciones distintas del mismo comando.
Combinar flags cortos y flags con valor
Cuando varios flags cortos no necesitan un valor, se pueden pegar detrás de un solo guion. Por eso -la es lo mismo que -l -a:
tar -xzvf backup.tar.gz
# es exactamente lo mismo que:
tar -x -z -v -f backup.tar.gz
Aquí -x extrae, -z descomprime con gzip y -v muestra cada archivo a medida que lo procesa (modo verboso). Pero -f es distinto: necesita un valor — el nombre del archivo, backup.tar.gz. Por eso -f va al final del combo: el valor que sigue le pertenece a esa última letra, no al bloque completo.
Cuando una opción necesita un valor, hay varias formas válidas de escribirlo:
head -n 5 notes.txt # opción corta, valor separado por un espacio
head -n5 notes.txt # opción corta, valor pegado (también válido)
head --lines=5 notes.txt # opción larga, valor con el signo =
head --lines 5 notes.txt # opción larga, valor separado por un espacio
Con opciones largas, el signo = es la forma estándar de unir la opción a su valor sin ambigüedad — más adelante vas a ver por qué escribirlo con espacios alrededor del = no funciona.
Por qué los espacios separan (y para qué sirven las comillas)
Antes de que el programa reciba un solo argumento, la shell ya troceó toda la línea que escribiste en pedazos, usando el espacio como separador. Cada pedazo se convierte en un argumento distinto. Esto tiene una consecuencia que sorprende a casi todo el mundo la primera vez:
mkdir new folder
ls
Qué esperar:
new folder
mkdir no recibió un solo argumento ("new folder"); recibió dos ("new" y "folder") y creó dos carpetas separadas, porque la shell partió la línea en el espacio antes de que mkdir viera nada.
Para que un espacio forme parte de un solo argumento, tienes que decirle a la shell que no lo trate como separador. Las comillas hacen exactamente eso:
mkdir "new folder"
ls
Qué esperar:
new folder
Ahora sí es una sola carpeta, con un espacio en el nombre. El mismo resultado se logra escapando el espacio con una barra invertida: mkdir new\ folder. Las comillas dobles ("...") y simples ('...') funcionan igual para este caso; la diferencia entre ambas aparece cuando usas variables dentro del texto, algo que no necesitas todavía.
El separador --: cuando un argumento parece una opción
¿Qué pasa si el archivo que quieres borrar se llama -verbose.log, con un guion al principio? Si escribes rm -verbose.log, el programa intenta interpretar eso como una opción (o una combinación de flags cortos), no como un nombre de archivo — y probablemente falle con un error confuso o, peor, haga algo que no esperabas.
El separador -- resuelve esto: le dice al programa "todo lo que venga después es un argumento posicional, aunque empiece con guion, ya no una opción".
rm -- -verbose.log
Es una convención que casi todos los programas de línea de comandos respetan, no un truco particular de rm. Vale la pena recordarla para el día en que te topes con un nombre de archivo raro.
command not found: qué significa exactamente (y qué no)
Cuando presionas Enter, la shell toma la primera palabra de la línea y, antes de ejecutar nada, busca un programa con ese nombre exacto dentro de una lista de carpetas guardada en la variable de entorno PATH, en orden, deteniéndose en la primera coincidencia. Si ninguna de esas carpetas tiene un programa con ese nombre, la shell nunca llega a "ejecutar" nada: simplemente responde con algo como esto y termina con el código de salida 127:
zsh: command not found: gitt
Lo que sí significa: la shell no encontró, en las carpetas que conoce, un programa que se llame exactamente así.
Lo que no significa:
- No significa necesariamente que el programa no esté instalado en tu máquina — puede estar instalado en una carpeta que simplemente no forma parte de tu
PATH. - No significa que haya algo mal con tus argumentos — el error ocurre antes de que la shell llegue siquiera a mirarlos.
- No es lo mismo que
No such file or directory, un error distinto que aparece cuando el programa sí se encontró y sí se ejecutó, pero uno de sus argumentos (un archivo o una ruta) es el que no existe.
Ergonomía que ahorra horas desde el primer día
Un puñado de atajos que usarás en cada sesión de terminal, desde hoy:
- Flechas ↑ / ↓ — historial: la shell recuerda cada comando que escribiste durante la sesión (y lo guarda entre sesiones en un archivo como
~/.bash_historyo~/.zsh_history). La flecha hacia arriba trae el comando anterior sin tener que retiparlo; la flecha hacia abajo avanza de vuelta. - Tab — autocompletado: empieza a escribir el nombre de un comando, archivo o carpeta y presiona Tab. Si hay una sola posibilidad, la shell completa el resto por ti; si hay varias, presionando Tab dos veces te muestra las opciones. Ahorra tipeo y evita errores de dedo en nombres largos.
- Ctrl+C — abortar: envía una señal de interrupción al proceso que está corriendo en primer plano ahora mismo y lo detiene. Es tu botón de pánico cuando un comando quedó colgado o entraste a un modo que no reconoces.
- Ctrl+L — limpiar pantalla: limpia lo que se ve en pantalla (equivalente al comando
clear), pero no borra tu historial ni lo que ya ejecutaste, solo el desorden visual. - Ctrl+A / Ctrl+E — moverte dentro de la línea:
Ctrl+Alleva el cursor al principio de la línea que estás escribiendo;Ctrl+Elo lleva al final. Son atajos heredados del modo de edición estilo Emacs que bash y zsh usan por defecto, y funcionan igual en macOS, Linux y dentro de WSL, porque en los tres casos estás frente a la misma bash o zsh.
Errores comunes
1. Confundir command not found con No such file or directory (conceptual). Qué pasa: ves un error y asumes que "el comando está mal" cuando en realidad el problema es un argumento, o al revés. Por qué ocurre: ambos mensajes suenan parecido ("no encontré algo") pero corresponden a fases distintas: command not found es la shell fallando al buscar el programa; No such file or directory es el programa, ya en marcha, fallando al buscar un archivo o ruta que le pasaste como argumento. Cómo detectarlo: fíjate en qué palabra aparece pegada al error — si es el nombre del comando, es la primera fase; si es un nombre de archivo o ruta, es la segunda. Cómo corregirlo: si es la primera, revisa que escribiste bien el nombre del programa y que está instalado; si es la segunda, revisa la ruta o el nombre del archivo, no el comando.
2. Olvidar las comillas en un argumento con espacios. Qué pasa: escribes mkdir new folder esperando una carpeta y terminas con dos. Por qué ocurre: la shell trocea la línea por espacios antes de que el programa vea nada; cada espacio es, para ella, el final de un argumento y el comienzo del siguiente. Cómo detectarlo: ejecuta ls después y verás más entradas de las que esperabas. Cómo corregirlo: envuelve el argumento completo entre comillas (mkdir "new folder") o escapa el espacio con una barra invertida (mkdir new\ folder).
3. Escribir espacios alrededor del = en una opción larga con valor (conceptual). Qué pasa: escribes head --lines = 5 notes.txt pensando que es equivalente a --lines=5, y el programa se queja de una opción desconocida o de un argumento inesperado. Por qué ocurre: la shell ya trozó esa línea en espacios antes de que head la viera — recibió cuatro pedazos (--lines, =, 5, notes.txt), no una opción con su valor. El = sin espacios funciona porque, sin espacios de por medio, sigue siendo un solo pedazo. Cómo detectarlo: el programa se queja de una opción que no reconoce o de argumentos sobrantes. Cómo corregirlo: sin espacios alrededor del = (--lines=5), o usa la forma separada por un solo espacio sin = (--lines 5).
Ejercicios
1. Dado el comando tar -xzvf backup.tar.gz -C /tmp/restore, identifica: el comando, qué flags están combinados y cuál de ellos lleva un valor, y cuáles son los argumentos con valor.
Ver solución
Comando: tar.
Flags combinados: -xzvf es en realidad cuatro flags cortos pegados — -x (extraer), -z (descomprimir con gzip), -v (modo verboso) y -f (el siguiente valor es el archivo a leer). De esos cuatro, solo -f necesita un valor, y por eso va último dentro del combo.
Flag separado: -C es un flag distinto, escrito aparte, que también lleva un valor.
Argumentos con valor: backup.tar.gz le pertenece a -f (el archivo que tar va a leer) y /tmp/restore le pertenece a -C (el directorio al que tar debe moverse antes de extraer).
Por qué funciona: es el mismo patrón que ls -la, con la particularidad de que un flag que necesita un valor (-f) debe ir al final del combo, porque el valor que sigue en la línea le pertenece a esa última letra.
2. Crea, con un solo comando, una carpeta llamada exactamente weekly report (con un espacio) dentro de tu carpeta personal. No debe crear dos carpetas.
Ver solución
mkdir "weekly report"
(También válido: mkdir 'weekly report' o mkdir weekly\ report.)
Por qué funciona: las comillas le dicen a la shell que trate el espacio como parte de un solo argumento, en vez de como el separador entre dos. mkdir recibe un único argumento y crea una única carpeta.
3. Tienes en tu carpeta actual un archivo que, por accidente, se llama -1.txt (empieza con un guion). Escribe el comando para borrarlo con rm sin que la shell lo interprete como una opción.
Ver solución
rm -- -1.txt
(También válido: rm ./-1.txt, porque anteponer ./ hace que el nombre ya no empiece literalmente con un guion.)
Por qué funciona: -- le indica a rm que todo lo que sigue es un argumento posicional, no una opción, aunque comience con guion.
4. Ejecuta a propósito un comando que no existe (por ejemplo, escribe mal el nombre de un programa que sí tienes instalado). Explica, con lo aprendido en esta lección, qué significa exactamente el error que obtienes y qué NO significa.
Ver solución
Por ejemplo, si escribes gitt status en vez de git status, vas a ver algo como:
zsh: command not found: gitt
Significa que la shell buscó, en cada carpeta listada en la variable PATH, un programa llamado exactamente gitt, y no lo encontró en ninguna.
No significa que git (el programa real) no esté instalado — de hecho probablemente sí lo esté. Tampoco significa que haya algo mal con el argumento status: el error ocurrió antes de que la shell llegara siquiera a considerar los argumentos, porque ni pudo identificar qué programa ejecutar.
Por qué funciona: distinguir esto de un error de "archivo no encontrado" (que vendría del programa una vez que sí arrancó) es justo lo que evita que pierdas tiempo revisando el lugar equivocado la próxima vez que te topes con un error parecido.
Resumen y siguiente paso
Antes de avanzar, deberías poder:
- separar cualquier comando en comando, opciones y argumentos con solo mirarlo;
- reconocer cuándo varios flags cortos están combinados y por qué uno con valor debe ir al final del combo;
- usar comillas cuando un argumento tiene espacios;
- usar
--cuando un argumento empieza con guion; - explicar con precisión qué significa (y qué no significa)
command not found; - moverte por la línea de comandos con flechas, Tab,
Ctrl+C,Ctrl+L,Ctrl+AyCtrl+Esin pensarlo.
Ya sabes leer la forma de un comando. Lo que todavía no sabes es qué opciones acepta un comando en particular que nunca viste antes — y ahí es exactamente donde entra la siguiente lección: leer el manual (man), --help y tldr para volverte autosuficiente sin depender de un tutorial cada vez que te topes con un programa nuevo.
Recursos
- GNU Coreutils —
lsinvocation — referencia oficial de los flags cortos y largos delsen GNU/Linux. - GNU grep manual — documenta
-i/--ignore-casey el resto de flags cortos y largos usados en los ejemplos. - GNU tar manual — detalla
-x,-z,-v,-fy por qué el orden dentro de un combo importa. - POSIX — Utility Argument Syntax — el estándar que define la convención del separador
--y la sintaxis de opciones que respetan casi todos los programas Unix. - GNU Bash Reference Manual — Readline Interaction — describe el historial, el autocompletado y los atajos de edición de línea (
Ctrl+A,Ctrl+E,Ctrl+L) heredados del modo Emacs.