system onlinepath: /guias/programacion/como-desarrollar-una-herramienta-de-linea-de-comandos/mode: knowledge_baselocal:
Programación · Nivel intermedio

Cómo desarrollar una herramienta de línea de comandos

Una buena herramienta de línea de comandos es rápida, predecible y encaja con las demás. Detrás de esa sensación hay un puñado de convenciones —argumentos, códigos de salida, entrada y salida estándar— que conviene conocer antes de escribir la primera línea.

16 min de lectura▣ Actualizada el ◇ Por Underc0de
Respuesta rápida

Una CLI (interfaz de línea de comandos) es un programa que se usa escribiendo comandos en la terminal en lugar de con ventanas y botones. Desarrollar una buena CLI no es solo «que funcione»: es que se comporte como esperan la persona y las otras herramientas, siguiendo un puñado de convenciones. Las piezas de una CLI son los argumentos (lo que va después del nombre del comando: copiar origen destino), las opciones o flags (que modifican el comportamiento: -v o --verbose, con forma corta y larga) y los subcomandos (verbos que agrupan funciones, como git commit). El programa se comunica por tres canales estándar: lee de stdin (entrada estándar), escribe los resultados en stdout (salida estándar) y los mensajes de error o diagnóstico en stderr (error estándar) —separarlos permite encadenar herramientas con tuberías sin que los avisos contaminen los datos—. Al terminar, devuelve un código de salida: 0 si todo fue bien, distinto de cero si hubo error; esto es lo que permite a los scripts saber si tu herramienta tuvo éxito. Las buenas prácticas que la vuelven usable: ofrecer --help claro, mensajes de error útiles a stderr, salir con el código correcto, no pedir cosas de forma interactiva cuando se la usa en un script, y comportarse de forma predecible. Casi cualquier lenguaje sirve —Python, Go, Node.js, Rust—, y todos tienen bibliotecas para parsear argumentos sin hacerlo a mano.

Ver índice de contenidos
  1. 01Qué es una CLI
  2. 02Las partes de una CLI
  3. 03Convenciones que la hacen usable
  4. 04Errores frecuentes
  5. 05Preguntas frecuentes
  6. 06Fuentes

Qué es una CLI

Una CLI (command-line interface) es un programa que se controla escribiendo texto en la terminal, frente a una GUI (interfaz gráfica) que se maneja con ratón y ventanas. Aunque parezca «lo viejo», las CLI siguen siendo centrales en programación porque son rápidas, scriptables y automatizables: se pueden encadenar, meter en tareas programadas y ejecutar sin intervención humana.

Por qué merece la pena hacer una CLI

Una herramienta de línea de comandos es la forma más directa de empaquetar una utilidad para reutilizarla y compartirla. No necesita interfaz gráfica, arranca al instante, y su mayor virtud es que encaja con otras herramientas: la salida de una es la entrada de la siguiente. Esa componibilidad —la filosofía de las herramientas pequeñas que hacen una cosa bien y se combinan— es la razón por la que la terminal sigue siendo tan potente para automatizar tareas.

Las partes de una CLI

La anatomía de una herramienta de línea de comandos, desglosando las partes de un comando y los canales por los que se comunica. En la parte superior se muestra un comando de ejemplo escrito en la terminal, descomponiéndolo en sus elementos. El primer elemento es el nombre del programa o comando, que identifica la herramienta que se ejecuta. El segundo elemento son los subcomandos, que son verbos que agrupan funciones dentro de una misma herramienta, como en el caso de un sistema de control de versiones cuyo comando principal va seguido de subcomandos como confirmar o clonar; se explica que los subcomandos permiten organizar herramientas con muchas funciones. El tercer elemento son las opciones o banderas, que modifican el comportamiento del comando y suelen tener una forma corta de una sola letra precedida de un guion y una forma larga más descriptiva precedida de dos guiones, como una opción para aumentar el detalle de la salida; se explica que algunas opciones son interruptores de encendido y apagado y otras reciben un valor. El cuarto elemento son los argumentos, que son los datos sobre los que actúa el comando, como los nombres de archivos de origen y destino en una operación de copia. En la parte inferior se muestran los tres canales estándar de comunicación de un programa de línea de comandos. El primero es la entrada estándar, por la que el programa puede recibir datos, por ejemplo de otro programa encadenado. El segundo es la salida estándar, por la que el programa escribe sus resultados normales, y que es la que se conecta a la entrada de la siguiente herramienta cuando se encadenan comandos mediante tuberías. El tercero es el error estándar, un canal separado por el que el programa escribe los mensajes de error y de diagnóstico, de modo que estos no se mezclen con los datos de la salida estándar y no contaminen el encadenamiento. Finalmente se muestra el código de salida que el programa devuelve al terminar, con el valor cero indicando que todo fue bien y un valor distinto de cero indicando que hubo un error, y se resalta que este código es lo que permite a los scripts y a otras herramientas saber si la ejecución tuvo éxito o no. El diagrama resalta que respetar estas partes y canales estándar es lo que hace que una herramienta de línea de comandos sea predecible, usable y capaz de encajar y combinarse con las demás. Estilo oscuro de programación, con el comando descompuesto y etiquetado arriba y los canales de entrada, salida, error y el código de salida representados debajo con flechas.
La anatomía de una CLI: nombre, subcomandos (verbos que agrupan funciones), opciones o flags (con forma corta y larga) y argumentos (los datos). Se comunica por tres canales —stdin, stdout y stderr— y devuelve un código de salida que indica éxito o error.

Entender estas piezas es entender cómo la persona (y los scripts) van a hablar con tu herramienta:

PiezaQué esEjemplo
ArgumentoEl dato sobre el que actúacopiar origen destino
Opción / flagModifica el comportamiento (corta y larga)-v / --verbose
SubcomandoVerbo que agrupa funcionesgit commit
stdin / stdout / stderrCanales de entrada, salida y errorDatos por stdout, avisos por stderr
Código de salidaÉxito (0) o error (≠0) al terminarexit 1
# Python: una CLI mínima con argparse (parsea argumentos por vos)
import argparse, sys

parser = argparse.ArgumentParser(description="Saluda a alguien")
parser.add_argument("nombre")                 # argumento posicional
parser.add_argument("-m", "--mayus", action="store_true")  # opción
args = parser.parse_args()

saludo = f"Hola, {args.nombre}"
print(saludo.upper() if args.mayus else saludo)   # resultado a stdout
sys.exit(0)                                       # código de salida: todo bien

Convenciones que la hacen usable

La diferencia entre una CLI que da gusto usar y una que frustra está en respetar lo que la gente ya espera. No hay que inventar: hay que cumplir las convenciones.

  • Ofrecer --help y -h. Con una descripción, el uso y las opciones. Es lo primero que la gente prueba.
  • Separar datos de mensajes. Los resultados a stdout; los avisos, progreso y errores a stderr. Así las tuberías no se contaminan.
  • Devolver el código de salida correcto. 0 éxito, distinto de cero error. Es como los scripts saben si funcionó.
  • Mensajes de error claros y accionables. Qué falló y qué hacer, no un volcado de pila.
  • No ser interactivo por sorpresa. Si detecta que no hay una persona (se usa en un script), no preguntar; ofrecer flags para todo.
  • Leer de stdin cuando tenga sentido. Permite encadenar: cat datos | miherramienta.
  • Ser predecible y silencioso por defecto. Hacer lo esperado, sin ruido; el detalle, bajo --verbose.
i
No parsees argumentos a mano

Leer -v, --output=archivo, combinar flags, gestionar valores y generar el --help tiene muchos casos límite. Cada lenguaje tiene bibliotecas estándar o muy usadas para esto —argparse en Python, flag y otras en Go, distintas opciones en Node.js y Rust—. Usalas: te dan el parseo, la validación y la ayuda formateada gratis, y respetan las convenciones POSIX que la gente espera. Escribir tu propio parser suele terminar en una CLI que se comporta de forma rara en los casos que no anticipaste.

Errores frecuentes

  • Escribir los errores en stdout. Contamina los datos y rompe las tuberías; los errores van a stderr.
  • Devolver siempre código 0. Un script no puede distinguir éxito de fallo; devolver ≠0 cuando algo sale mal.
  • No incluir --help. Obliga a leer el código para saber cómo se usa.
  • Preguntar de forma interactiva en un script. Bloquea la automatización; permitir pasar todo por flags o stdin.
  • Parsear argumentos a mano. Lleno de casos límite; usar una biblioteca del lenguaje.
  • Ser ruidoso por defecto. Inundar de mensajes molesta y ensucia los logs; el detalle, bajo --verbose.
  • Mensajes de error crípticos. Decir qué pasó y cómo arreglarlo, no solo «error».

Preguntas frecuentes

¿Qué es una herramienta de línea de comandos?

Una herramienta de línea de comandos, o CLI por sus siglas en inglés, es un programa que se utiliza escribiendo comandos de texto en la terminal, en lugar de interactuar con él mediante ventanas, botones y ratón como ocurre con las aplicaciones de interfaz gráfica. El usuario escribe el nombre del programa seguido, si procede, de subcomandos, opciones y argumentos, y el programa ejecuta la acción correspondiente y devuelve un resultado, normalmente también en forma de texto. Aunque a primera vista pueda parecer un modo de trabajo anticuado frente a las interfaces gráficas, las herramientas de línea de comandos siguen siendo centrales en el mundo de la programación, la administración de sistemas y la automatización, y lo son por varias razones de peso. En primer lugar, son rápidas y ligeras, ya que arrancan de inmediato y no requieren cargar una interfaz gráfica. En segundo lugar, y esto es lo más importante, son automatizables y componibles: al comunicarse mediante texto y canales estándar, se pueden encadenar unas con otras, de modo que la salida de una alimente la entrada de la siguiente, y se pueden incluir en scripts y tareas programadas que se ejecutan sin intervención humana. Esta capacidad de combinarse y automatizarse es la que hace que la terminal siga siendo una herramienta tan poderosa para quienes desarrollan software o gestionan sistemas. Desarrollar una herramienta de línea de comandos es, además, la forma más directa de empaquetar una utilidad propia para reutilizarla y compartirla, sin la complejidad de construir una interfaz gráfica. Sin embargo, hacer una buena CLI no consiste solo en que el programa haga su tarea, sino en que se comporte siguiendo un conjunto de convenciones bien establecidas sobre cómo recibir argumentos y opciones, cómo comunicar resultados y errores a través de los canales adecuados y cómo indicar mediante un código de salida si la ejecución tuvo éxito, de manera que la herramienta resulte predecible, usable y capaz de encajar con las demás piezas del ecosistema.

¿Qué diferencia hay entre argumentos, opciones y subcomandos?

Los argumentos, las opciones y los subcomandos son las tres clases de elementos que pueden aparecer al escribir un comando, y cada uno cumple un papel distinto en cómo se le indica a la herramienta qué hacer. Los argumentos, también llamados argumentos posicionales, son los datos sobre los que la herramienta actúa, y su significado depende de la posición que ocupan; por ejemplo, en un comando que copia un archivo, el primer argumento podría ser el archivo de origen y el segundo el destino, de modo que son la información esencial que el comando necesita para operar. Las opciones, también conocidas como banderas o flags, sirven para modificar el comportamiento del comando, y se distinguen porque suelen ir precedidas de guiones; existe habitualmente una forma corta, consistente en un guion seguido de una sola letra, y una forma larga más descriptiva, consistente en dos guiones seguidos de una palabra, y ambas suelen ser equivalentes. Algunas opciones funcionan como interruptores que simplemente activan o desactivan un comportamiento, como una opción que hace que la salida sea más detallada, mientras que otras reciben un valor asociado, como una opción que indica en qué archivo escribir el resultado. Los subcomandos son verbos o palabras que agrupan funciones dentro de una misma herramienta, y resultan muy útiles cuando un programa ofrece muchas capacidades distintas, ya que permiten organizarlas de forma clara; un ejemplo muy conocido es el de los sistemas de control de versiones, cuyo comando principal va seguido de subcomandos que indican la acción concreta, como confirmar cambios, clonar un repositorio o consultar el estado, y cada subcomando puede tener a su vez sus propios argumentos y opciones. En conjunto, un comando bien diseñado combina estos elementos de forma coherente: el nombre del programa, opcionalmente un subcomando que indica la acción, las opciones que ajustan el comportamiento y los argumentos que aportan los datos concretos. Comprender esta estructura es fundamental tanto para usar herramientas de línea de comandos como para diseñarlas de manera que resulten intuitivas y coherentes con las convenciones que los usuarios ya conocen.

¿Qué son stdin, stdout y stderr?

La entrada estándar, la salida estándar y el error estándar, conocidas habitualmente por sus nombres en inglés stdin, stdout y stderr, son los tres canales de comunicación estándar que todo programa de línea de comandos tiene a su disposición para recibir y emitir información, y comprender su papel es esencial para desarrollar herramientas que se comporten correctamente y encajen con las demás. La entrada estándar es el canal por el que un programa puede recibir datos de entrada, que pueden provenir del teclado del usuario o, muy frecuentemente, de la salida de otro programa que se le encadena; leer de la entrada estándar cuando tiene sentido permite que la herramienta reciba datos de una tubería y forme parte de una cadena de procesamiento. La salida estándar es el canal por el que el programa emite sus resultados normales, es decir, la información que constituye el producto de su trabajo, y es precisamente este canal el que se conecta con la entrada estándar de la siguiente herramienta cuando se encadenan comandos mediante tuberías, lo que hace posible componer herramientas pequeñas para realizar tareas complejas. El error estándar es un canal separado, distinto de la salida estándar, por el que el programa emite los mensajes de error, las advertencias y la información de diagnóstico o de progreso. La razón de que exista este tercer canal separado es fundamental: al enviar los mensajes de error y diagnóstico por un canal distinto del de los datos, se evita que esos mensajes contaminen los resultados cuando la salida se encadena con otra herramienta o se guarda en un archivo, de modo que los datos permanecen limpios y los avisos siguen siendo visibles para el usuario. Por eso una de las buenas prácticas más importantes al desarrollar una CLI es escribir siempre los resultados en la salida estándar y reservar el error estándar para los mensajes de error, las advertencias y el progreso. Este diseño de tres canales, heredado de la tradición de los sistemas tipo Unix, es lo que permite la enorme flexibilidad de la línea de comandos, donde las herramientas se combinan libremente redirigiendo y encadenando estos flujos de texto.

¿Por qué son importantes los códigos de salida?

Los códigos de salida son importantes porque constituyen el mecanismo mediante el cual un programa de línea de comandos comunica, al terminar su ejecución, si esta tuvo éxito o si se produjo algún error, y esa información es imprescindible para la automatización y para que las herramientas puedan coordinarse entre sí. Cuando un programa finaliza, devuelve al sistema un número entero conocido como código de salida o código de estado, y por convención el valor cero significa que todo fue bien, es decir, que la ejecución se completó con éxito, mientras que cualquier valor distinto de cero indica que hubo algún tipo de error o de finalización anómala, pudiendo emplearse distintos valores para distinguir distintos tipos de fallo. La relevancia de este código radica en que permite a otros programas, a los scripts y al propio intérprete de comandos saber, de forma fiable y sin tener que interpretar el texto de la salida, si la herramienta cumplió su cometido. Esto es la base de la automatización: un script que ejecuta una serie de comandos puede comprobar el código de salida de cada uno para decidir si continúa, si se detiene o si toma una acción alternativa, y construcciones habituales del intérprete de comandos permiten encadenar acciones condicionadas al éxito o al fallo del comando anterior precisamente gracias a estos códigos. Si una herramienta devolviera siempre el valor cero, incluso cuando ha fallado, rompería esta coordinación, ya que los scripts creerían que todo fue bien y continuarían como si nada, con consecuencias potencialmente graves; por eso uno de los errores más importantes que hay que evitar al desarrollar una CLI es no devolver el código de salida adecuado. La buena práctica consiste en devolver cero únicamente cuando la operación se completa correctamente y un valor distinto de cero cuando ocurre un error, idealmente usando códigos coherentes para los distintos tipos de fallo, de modo que la herramienta se integre bien en flujos automatizados y sea un ciudadano fiable del ecosistema de la línea de comandos. En definitiva, los códigos de salida son un pequeño detalle que resulta decisivo para que las herramientas puedan combinarse y automatizarse de forma robusta.

¿Qué lenguaje conviene para escribir una CLI?

Para escribir una herramienta de línea de comandos sirve prácticamente cualquier lenguaje de programación de propósito general, y la elección adecuada depende más del contexto, de los objetivos y de las preferencias que de una supuesta superioridad de un lenguaje sobre otro, ya que cada uno ofrece ventajas distintas. Python es una opción muy popular para las CLI por su sencillez, su legibilidad y su amplia biblioteca estándar, que incluye herramientas para procesar argumentos de forma cómoda, lo que lo hace ideal para scripts y utilidades de automatización que se desarrollan con rapidez; su principal contrapartida es que requiere que el intérprete esté disponible en la máquina donde se ejecuta. Go se ha vuelto muy apreciado para crear herramientas de línea de comandos porque compila a un único binario autónomo sin dependencias externas, lo que hace trivial distribuir la herramienta simplemente copiando un archivo, además de ofrecer buen rendimiento y facilidad para generar versiones para distintos sistemas operativos, razones por las que muchas herramientas modernas de sistemas están escritas en él. Node.js, basado en JavaScript, es una elección natural para quienes ya trabajan en ese ecosistema y permite aprovechar su enorme cantidad de paquetes, incluidos varios muy buenos para construir interfaces de línea de comandos. Rust es otra opción excelente cuando se busca máximo rendimiento y seguridad, y también compila a binarios autónomos, contando con bibliotecas muy potentes para el análisis de argumentos. Otros lenguajes como los del shell resultan adecuados para tareas sencillas y de pegamento entre comandos, aunque se vuelven difíciles de mantener en herramientas complejas. Un criterio práctico para decidir es tener en cuenta cómo se va a distribuir la herramienta, ya que si se necesita repartirla fácilmente a usuarios que no tienen un entorno concreto instalado, los lenguajes que compilan a un binario autónomo como Go o Rust tienen una ventaja clara, mientras que si se trata de utilidades internas o de automatización personal, la comodidad y la velocidad de desarrollo de Python o Node.js pueden pesar más. En cualquier caso, sea cual sea el lenguaje elegido, la recomendación transversal es apoyarse en las bibliotecas de análisis de argumentos que ese lenguaje ofrece en lugar de procesarlos manualmente, y respetar las convenciones comunes de las CLI, ya que eso es lo que realmente determina la calidad y la usabilidad de la herramienta, con independencia del lenguaje.

¿Cómo hago que mi CLI sea fácil de usar y de automatizar?

Para que una herramienta de línea de comandos sea fácil de usar por las personas y a la vez fácil de automatizar en scripts, conviene seguir un conjunto de buenas prácticas y convenciones bien establecidas que, en esencia, buscan que la herramienta se comporte de forma predecible y respete lo que los usuarios y las demás herramientas ya esperan. Una primera práctica fundamental es ofrecer una ayuda clara accesible mediante las opciones habituales de ayuda, que muestre una descripción de la herramienta, cómo se usa y qué argumentos y opciones admite, ya que suele ser lo primero que alguien prueba al encontrarse con un comando nuevo. En segundo lugar, es esencial usar correctamente los canales de comunicación, escribiendo los resultados en la salida estándar y reservando el error estándar para los mensajes de error, las advertencias y el progreso, de modo que la salida de datos permanezca limpia y la herramienta pueda encadenarse con otras sin problemas. En tercer lugar, hay que devolver siempre el código de salida adecuado, cero cuando todo va bien y distinto de cero cuando ocurre un error, porque es la forma en que los scripts saben si la ejecución tuvo éxito. En cuarto lugar, los mensajes de error deben ser claros y accionables, explicando qué ha fallado y, en la medida de lo posible, cómo solucionarlo, en lugar de mostrar información técnica incomprensible. En quinto lugar, para no romper la automatización, la herramienta no debería requerir interacción por sorpresa cuando se ejecuta dentro de un script, ofreciendo en su lugar opciones para proporcionar toda la información necesaria mediante argumentos, banderas o la entrada estándar, y detectando cuándo no hay una persona al otro lado. También resulta muy valioso permitir leer datos de la entrada estándar cuando tiene sentido, para poder encadenar la herramienta con otras mediante tuberías, y comportarse de forma silenciosa y predecible por defecto, haciendo lo esperado sin generar ruido innecesario y reservando la salida detallada para cuando se solicita expresamente con una opción de verbosidad. Finalmente, conviene apoyarse en las bibliotecas de análisis de argumentos del lenguaje elegido en lugar de procesarlos manualmente, ya que estas respetan las convenciones estándar y evitan comportamientos extraños en los casos límite. Siguiendo estas pautas, la herramienta resultará intuitiva para las personas y, al mismo tiempo, un componente fiable y combinable dentro de flujos de trabajo automatizados.

Fuentes

Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.

Aportes de la comunidad Underc0de

  1. Underc0de, foro. Sección Programación. Herramientas y scripts.
  2. Underc0de, foro. Sección GNU/Linux. Terminal y automatización.

Documentación oficial

  1. GNU. Command-Line Interfaces (GNU Coding Standards). Convenciones de opciones y argumentos.
  2. clig.dev. Command Line Interface Guidelines. Guía moderna de diseño de CLIs.
  3. The Open Group. POSIX Utility Conventions. Convenciones estándar de argumentos.
  4. MDN. JavaScript. Base para CLIs escritas en Node.js.