Dos herramientas de línea de comandos que sirven para descargar archivos a través de HTTP, instaladas en casi todos los ordenadores, comparadas sin cesar y de las que rara vez se distingue su utilidad.
La fuente más fiable sobre la diferencia es, afortunadamente, la comparación que publica el propio mantenedor de curl, un documento que incluye una sección específica sobre lo que wget hace mejor que curl. Todas las afirmaciones objetivas que figuran a continuación se remontan a ese documento o a los propios manuales de los proyectos, en lugar de basarse en la impresión personal de alguien, lo cual es importante en una comparación que, con tanta frecuencia, se escribe de memoria.
Somos Geonode, vendemos proxies, y la nota de honestidad es breve: ninguna de las dos herramientas necesita un proxy para la gran mayoría de los usos que la gente les da. Descargar un archivo, llamar a una API, comprobar si un servicio responde… nada de eso requiere uno. Existe una diferencia real y poco documentada entre ambas en cuanto a la compatibilidad con proxies, y hay una sección al respecto más abajo, pero si has llegado hasta aquí para elegir un programa de descarga, puedes ignorarla sin problema.
El resumen útil es que estas herramientas se crearon con modelos mentales diferentes, y casi todas las diferencias superficiales se derivan de ello. curl se comporta como cat: descarga algo y lo escribe en la salida estándar. wget se comporta como cp: descarga algo y lo escribe en un archivo. Esa es la perspectiva del propio mantenedor, y una vez que la entiendes, los valores predeterminados de redireccionamiento, las diferencias entre opciones y la capacidad de recursividad dejan de parecer arbitrarias.
La recomendación breve, para quien la quiera antes de entrar en detalles: usa wget cuando quieras archivos en el disco, y curl para todo lo demás.
La diferencia en una sola frase
curl funciona, en palabras de su responsable de mantenimiento, «como el comando tradicional de Unix cat
». wget funciona «más bien como cp
».
Esa única distinción explica la mayor parte de lo que viene a continuación.
Qué significa en la práctica
curl https://example.com/file.txt # prints the contents to your terminal
wget https://example.com/file.txt # saves file.txt to the current directory
Ninguna de las dos opciones es incorrecta. Responden a preguntas diferentes.
El diseño de curl da por hecho que lo que quieres son los datos, y que lo que ocurra con ellos a continuación es asunto tuyo: canalizarlos, analizarlos, redirigirlos o leerlos. Escribir en la salida estándar es la opción más combinable, y por eso curl encaja de forma natural en las tuberías del shell.
El diseño de wget da por hecho que lo que quieres es el archivo. Elige el nombre del archivo, lo crea, muestra una barra de progreso y termina con algo en el disco.
Por qué las consecuencias son mayores de lo que parecen
Cuando la función de una herramienta es «guardar el archivo en el disco», hay toda una serie de comportamientos que resultan obviamente correctos: seguir las redirecciones, porque el archivo se ha movido; reintentar en caso de fallo, porque el objetivo es el archivo y no el intento; reanudar una descarga parcial, porque un archivo a medias no es lo que se busca. wget hace todo esto por defecto.
Cuando la tarea de una herramienta es «realizar esta transferencia y darme el resultado», los comportamientos correctos son diferentes: informar de lo que ha ocurrido en lugar de decidir por mí, hacer exactamente lo que se le ha pedido y dejar que quien la ha llamado se encargue del resto. curl informa de la redirección y se detiene, porque seguirla no era lo que se le había pedido.
Ninguno de los dos conjuntos de valores predeterminados es mejor. Son coherentes con fines distintos, y la mayor parte de la frustración que la gente siente con cualquiera de las dos herramientas proviene de esperar los supuestos de la otra.
Lo que hace curl y no hace wget
Según la comparación del mantenedor, y se trata de una lista considerable.
Es, ante todo, una biblioteca
curl incluye libcurl, descrita como una biblioteca con «una API estable que puede ser utilizada por todos y cada uno». Esta es la diferencia más importante y la menos visible desde una terminal.
libcurl está integrada en una enorme cantidad de software: enlaces de lenguaje, aplicaciones, dispositivos. La herramienta de línea de comandos es, en cierto sentido, una demostración de la biblioteca. wget es un programa; curl es un programa que se ejecuta sobre una biblioteca que utilizan otros programas.
Si alguna vez has utilizado las funciones cURL de PHP o un enlace HTTP de un lenguaje basado en libcurl, has utilizado curl sin ejecutar curl.
Muchos más protocolos
La lista publicada es extensa: «FTP(S), GOPHER(S), HTTP(S), SCP, SFTP, TFTP, TELNET, DICT, LDAP(S), MQTT, FILE, POP3(S), IMAP(S), SMB(S), SMTP(S), RTMP, RTSP y WS(S)».
wget admite HTTP, HTTPS y FTP. Para la web, eso suele ser suficiente. Para cualquier cosa relacionada con protocolos de correo, SFTP, MQTT o WebSocket, curl es la única de las dos opciones que entra en liza.
Versiones más recientes de HTTP
curl es compatible con HTTP 0.9, 1.0, 1.1, 2 y 3. Si necesitas comprobar cómo se comporta un servidor específicamente con HTTP/2 o HTTP/3, esa es una tarea para curl.
Más tipos de proxy
curl es compatible con proxies HTTPS y proxies SOCKS4 y SOCKS5. Esto figura entre las características que tiene curl y que wget no tiene, y tiene consecuencias reales; consulta la sección sobre proxies más abajo.
Transferencias paralelas
curl puede ejecutar múltiples transferencias simultáneas con -Z. Resulta útil a la hora de recuperar muchos recursos pequeños en los que la latencia de hacerlo de uno en uno es un factor determinante.
Transferencia bidireccional y envíos de formularios
Enviar datos, no solo recibirlos. Envíos de formularios multiparte, PUT, métodos arbitrarios. wget es, fundamentalmente, una herramienta de recuperación; curl es una herramienta de transferencia, y los envíos son un caso de primer orden.
Ya viene instalado en más equipos
curl viene preinstalado en macOS y en Windows 10 y 11. En un equipo con Windows sin nada instalado adicional, curl está disponible y wget, por lo general, no —lo cual tiene más importancia de la que debería para los scripts multiplataforma.
Lo que hace wget y no hace curl
Además, proviene del propio responsable del mantenimiento de curl, lo que hace que esta lista sea fiable.
Descarga recursiva
«La principal ventaja de wget frente a curl es su capacidad para descargar de forma recursiva».
Esta es la característica más importante y no es una función menor. wget puede seguir los enlaces de una página y descargar lo que encuentre, hasta una profundidad especificada, convirtiendo los enlaces para su visualización local sobre la marcha. Crear una copia de un sitio de documentación para leerlo sin conexión se hace con un solo comando.
wget -r -np -k -p https://example.com/docs/
Recursivo, sin directorios principales, convierte los enlaces para su visualización local y recupera elementos necesarios de la página, como imágenes y hojas de estilo.
curl no puede hacer esto en absoluto. curl recupera las URL que le indicas. No analiza el HTML, no descubre enlaces y no tiene el concepto de «sitio web». Si tu tarea consiste en «copiar esta sección de un sitio web», wget es la respuesta y no existe ningún equivalente de curl que merezca la pena probar.
Reanudación de descargas interrumpidas
wget «puede recuperarse de una descarga interrumpida prematuramente y continuar con la descarga». Con -c, una descarga interrumpida se reanuda desde donde se detuvo.
curl también puede hacerlo con -C -, pero el comportamiento de wget en cuanto a reintentos y reanudación es más automático y más tolerante, lo cual es importante cuando la transferencia es grande y la conexión no es fiable.
No necesita opciones para el caso obvio
wget descarga un archivo sin opciones. curl «necesita -o o -O» para escribir en un archivo en lugar de en la terminal.
Para la tarea más común que cualquiera realiza con cualquiera de las dos herramientas —descargar este archivo—, wget es el comando más breve, y ser más breve es una ventaja real en una herramienta que se utiliza a diario.
Valores predeterminados más sensatos para la descarga
wget «habilita más funciones de forma predeterminada: cookies, seguimiento de redireccionamientos y marca de tiempo».
Merece la pena destacar especialmente la marca de tiempo: con -N, wget solo vuelve a descargar un archivo si la versión remota es más reciente. Para la sincronización programada de un conjunto de archivos, este es precisamente el comportamiento adecuado y curl no tiene ningún equivalente directo.
Licencia
wget tiene licencia GPL v3; curl, MIT. Si vas a integrar cualquiera de los dos en un producto, es probable que esa diferencia sea más importante que cualquier característica de esta página.
Ajustes predeterminados que te hacen perder tiempo
Las diferencias que más probablemente te harán pasar una tarde llena de confusión.
Redirecciones
wget sigue las redirecciones por defecto. curl no lo hace.
Esta es la causa más habitual de que «curl no devuelva nada». El servidor respondió con un 301, curl lo notificó y se detuvo, y la salida estándar parece estar vacía.
curl -L https://example.com/moved # follow them
wget https://example.com/moved # already following them
No se trata de un descuido por parte de curl. Seguir una redirección significa realizar una solicitud que no has pedido, a un host que no has especificado, y el modelo de curl consiste en hacer lo que se le indica e informar del resto. El modelo de wget consiste en obtener el archivo, y el archivo se ha movido.
Destino de la salida
Ya se ha tratado anteriormente, pero merece la pena repetirlo porque es algo que confunde a la gente constantemente. «curl URL» muestra el resultado; «wget URL» lo guarda.
Gestión de errores
Ambos tienen una peculiaridad. «curl» trata un 404 como una transferencia correcta y sale con un código de salida cero: la transferencia funcionó, el servidor respondió. Utiliza «-f» para que los errores HTTP produzcan un código de salida distinto de cero.
wget, por defecto, devuelve un valor distinto de cero en caso de errores HTTP, lo cual es el comportamiento más intuitivo para un programa de descarga.
En scripts: curl -sSf es la combinación que conviene recordar, y su ausencia es una razón habitual por la que una tarea fallida parece estar funcionando.
Reintentos
wget realiza reintentos por defecto. curl no lo hace a menos que se le indique con --retry.
De nuevo, en consonancia con los modelos: un programa de descarga debe persistir, una herramienta de transferencia debe informar.
Consejos prácticos
Si estás escribiendo cualquier programa automatizado, configura el comportamiento de forma explícita en lugar de confiar en los valores predeterminados de cualquiera de las herramientas. curl -sSfL --max-time 30 explica lo que quieres. Lo mismo ocurre con wget --tries=3 --timeout=30. Los comandos explícitos siguen siendo comprensibles cuando los lee otra persona al cabo de un año.
Comparación
| Tarea | curl | wget |
|---|
| Imprimir en la terminal | curl URL | wget -O - URL |
| Guardar en un archivo | curl -O URL | wget URL |
| Guardar con el nombre elegido | curl -o name URL | wget -O name URL |
| Seguir redirecciones | curl -L URL | por defecto |
| Reanudar una descarga | curl -C - -O URL | wget -c URL |
| Solo encabezados | curl -I URL | wget --spider -S URL |
| Encabezado personalizado | curl -H "K: V" URL | wget --header="K: V" URL |
| Autenticación básica | curl -u user:pass URL | wget --user=u --password=p URL |
| Datos POST | curl -d "a=b" URL | wget --post-data="a=b" URL |
| Silencioso | curl -s URL | wget -q URL |
| Duplicar un sitio | no es posible | wget -m URL |
| Subir un archivo | curl -T file URL | no es posible |
| Usar SOCKS5 | curl -x socks5h://host URL | no de forma nativa |
| Transferencias paralelas | curl -Z ... | no compatible |
Cómo interpretar la tabla
La simetría se mantiene en las operaciones cotidianas: la mayoría de las tareas tienen un equivalente directo, con diferentes formas de escribir los parámetros que resultan más molestas que importantes.
Las cuatro filas marcadas como «no posibles» son donde realmente hay que tomar una decisión. La duplicación de un sitio solo se puede hacer con wget. La subida de archivos solo se puede hacer con curl. El uso de un proxy SOCKS solo se puede hacer con curl. Las transferencias en paralelo solo se pueden hacer con curl.
Si tu tarea se encuentra en una de esas filas, la comparación ha terminado y puedes dejar de leer. Si no es así, cualquiera de las dos herramientas funciona y deberías utilizar aquella con la que te sientas más cómodo.
Una nota sobre la colisión de opciones
«-O» significa cosas diferentes en las dos herramientas, y es una auténtica trampa.
En curl, -O significa «guardar utilizando el nombre de archivo de la URL» y -o name significa «guardar con este nombre». En wget, -O name significa «guardar con este nombre» y no hay necesidad de utilizar la otra opción.
Por lo tanto, curl -O y wget -O no son equivalentes, y un comando traducido sin cuidado entre ambas herramientas provocará un comportamiento inesperado.
Cuál utilizar según la tarea
Más bien una lista de recomendaciones que una conclusión definitiva.
Utiliza wget cuando
Quieras un archivo en el disco. Sin opciones, con barra de progreso y valores predeterminados sensatos. Este es el caso más habitual para la mayoría de la gente.
Quieres realizar una descarga espejo o recursiva. Es la única opción. wget -m o wget -r con los límites adecuados.
La conexión es poco fiable y el archivo es grande. Reintentos automáticos y reanudación -c.
Estás manteniendo sincronizada una copia local. -N, que marca con la fecha y hora, descarga solo lo que ha cambiado.
Quieres el comando más breve posible para una descarga sencilla en un script que va a leer otra persona.
Utiliza curl cuando
Estés trabajando con una API. Encabezados, métodos, cuerpos de solicitud y salida que se canaliza a un procesador JSON.
Necesitas enviar datos, no solo recuperarlos.
Estás depurando. -v y -w te muestran la solicitud tal y como se envió, la respuesta y los tiempos desglosados por fase. Esta es, con diferencia, la mayor ventaja de curl en el día a día.
Necesitas un protocolo más allá de HTTP y FTP.
Necesitas compatibilidad con proxies SOCKS o HTTPS.
Estás en Windows o macOS sin nada instalado, donde curl está presente y wget normalmente no.
Estás escribiendo algo que se convertirá en código, ya que los enlaces de libcurl hacen que la estructura del comando se traduzca de forma natural.
Utiliza ambos
La respuesta honesta para la mayoría de los entornos de trabajo. Son pequeños, son gratuitos y se desenvuelven bien en aspectos diferentes. Tener ambos instalados y recurrir al que mejor se adapte no es indecisión, sino el resultado lógico de que se trate de herramientas genuinamente diferentes.
Proxies en ambos
nuestro ámbito, y hay una diferencia importante que conviene conocer.
curl
# HTTP proxy
curl -x http://proxy.example.com:8080 https://example.com
# With credentials
curl -x http://user:pass@proxy.example.com:8080 https://example.com
# SOCKS5, with the proxy resolving hostnames
curl -x socks5h://proxy.example.com:1080 https://example.com
: curl admite proxies HTTP, proxies HTTPS y SOCKS4/SOCKS5
, todo ello a través de la misma opción -x
con un esquema.
wget
# Via environment variables
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
wget https://example.com
# With credentials
wget --proxy-user=user --proxy-password=pass https://example.com
wget lee las variables de entorno estándar de proxy y dispone de opciones para las credenciales de proxy.
La diferencia que importa
wget no admite SOCKS de forma nativa. La comparación de curl incluye SOCKS4 y SOCKS5
entre las cosas que admite curl y que wget no admite.
Si tu proxy es exclusivamente SOCKS, wget no puede utilizarlo directamente. Las soluciones habituales consisten en ejecutar wget a través de una herramienta como proxychains o en colocar un puente local de HTTP a SOCKS delante de él; ambas opciones funcionan, pero ambas añaden un componente que puede fallar de forma silenciosa.
Si tienes que elegir entre las dos opciones y SOCKS está en tu configuración, eso es lo que decide.
El detalle del DNS, otra vez
Vale la pena repetirlo porque se aplica siempre que se utiliza curl con SOCKS. socks5://
resuelve los nombres de host en tu equipo; socks5h://
envía el nombre de host al proxy. La primera filtra todos los hosts que visitas a tu resolutor local, aunque el tráfico se enrute correctamente, y puede proporcionarte una dirección regionalmente errónea para sitios con una infraestructura dependiente de la ubicación.
Utiliza socks5h://
a menos que tengas una razón específica para no hacerlo.
Y la parte en la que nos echamos para atrás
Si estás descargando un archivo, llamando a una API para la que tienes credenciales o comprobando si un servicio está activo, no necesitas ningún proxy. Los proxies tienen su razón de ser en estas herramientas para la comprobación geográfica y para trabajos de gran volumen sujetos a límites de velocidad por dirección. Para todo lo demás, solo añaden latencia, un punto de fallo y una factura.
Cuando ninguna de las dos es la herramienta adecuada
Hay varias situaciones habituales en las que se necesita otra cosa, y recurrir a cualquiera de estas herramientas supone perder toda una tarde.
La página se genera mediante JavaScript. Ambas herramientas recogen lo que envía el servidor. Si el contenido se ensambla posteriormente en el navegador, lo que obtienes es una página vacía y ninguna opción de «flag» lo soluciona. Necesitas un navegador sin interfaz gráfica —Playwright, Puppeteer o similar—.
Necesitas interactuar con la página. Hacer clic, desplazarte, rellenar formularios, esperar a que aparezca algo. La respuesta es la misma.
Estás creando algo que se pueda mantener en código. Recurrir a curl desde una aplicación es un atajo habitual que acaba quedando obsoleto. Utiliza la biblioteca HTTP de tu lenguaje o los enlaces de libcurl y obtén una gestión adecuada de los errores.
Necesitas sincronizar un directorio en ambos sentidos. rsync es la herramienta adecuada, y lo hace mucho mejor que el wget recursivo.
Estás transfiriendo datos entre servidores que controlas. scp, rsync o sftp: están diseñadas específicamente para ello, son más rápidas y gestionan correctamente los permisos y las transferencias parciales.
Necesitas inspeccionar o modificar el tráfico en tránsito. Una herramienta de proxy de interceptación es el instrumento adecuado.
Estás descargando contenido multimedia de una plataforma de vídeo. Las herramientas diseñadas específicamente se encargan del análisis del manifiesto y del ensamblaje de la transmisión, algo que ninguna de estas opciones intenta hacer.
Los datos se ofrecen de otra forma. Una API, una descarga masiva, un conjunto de datos público, una fuente RSS. Comprobarlo lleva diez minutos y, a menudo, pone fin al proyecto antes de que empiece.
Precaución con la descarga recursiva
Una advertencia específica sobre wget -r, que es potente y fácil de dirigir hacia algo que no era tu intención.
Sin -np, puede subir a los directorios superiores. Sin --level, puede descender mucho más allá. Sin --wait, realizará solicitudes tan rápido como responda el servidor, lo cual es una falta de respeto hacia la infraestructura ajena y una buena forma de que te bloqueen.
Como mínimo: wget -r -np --level=3 --wait=1 URL. Y comprueba primero robots.txt y las condiciones de uso del sitio: wget respeta robots.txt por defecto, y desactivarlo es una decisión más que una simple comodidad.
Preguntas frecuentes
¿Cuál es la diferencia entre curl y wget?
curl funciona como cat: recupera datos y los escribe en la salida estándar. wget funciona como cp: recupera datos y guarda un archivo. curl admite muchos más protocolos, subidas, proxies SOCKS y transferencias paralelas; wget puede descargar de forma recursiva y crear copias espejo de sitios web, algo que curl no puede hacer en absoluto.
¿Es curl mejor que wget?
Ninguno de los dos es mejor. curl es una herramienta de transferencia que cuenta con una biblioteca y una gama de protocolos mucho más amplia; wget es un programa de descarga con mejores ajustes predeterminados para la descarga y una capacidad recursiva única. A la mayoría de la gente le conviene tener ambos.
¿Puede curl descargar de forma recursiva como wget?
No. curl recupera las URL que se le proporcionan y no analiza el HTML ni descubre enlaces. La descarga recursiva y la creación de copias espejo de sitios web son exclusivas de wget, y el propio mantenedor de curl señala esto como la principal fortaleza de wget.
¿Por qué curl no sigue las redirecciones?
Por diseño. curl informa de lo que dice el servidor en lugar de realizar solicitudes que no has pedido. Añade -L para que las siga. wget las sigue por defecto porque su objetivo es recuperar el archivo, y este se ha movido.
¿Qué es más rápido, curl o wget?
Para una sola transferencia, la diferencia es insignificante: ambos están limitados por la red. curl puede ejecutar varias transferencias en paralelo con -Z, lo que lo hace significativamente más rápido a la hora de recuperar muchos recursos pequeños.
¿Admite wget los proxies SOCKS?
No de forma nativa. curl admite proxies SOCKS4, SOCKS5 y HTTPS; wget utiliza las variables de entorno estándar de los proxies HTTP. Para utilizar SOCKS con wget, necesitas un envoltorio como proxychains o un puente local.
¿Cuál debería utilizar en un script?
Cualquiera de las dos, con opciones explícitas. Para API y cualquier situación en la que se inspeccione la respuesta, curl -sSfL --max-time 30. Para descargar archivos, wget --tries=3 --timeout=30. No confíes en los valores predeterminados de ninguna de las dos herramientas en la automatización.
¿Vienen instalados por defecto curl o wget?
curl viene preinstalado en macOS y en Windows 10 y 11. wget es estándar en la mayoría de las distribuciones de Linux, pero suele no estar presente en macOS ni en Windows. Para scripts multiplataforma, es más seguro dar por hecho que se dispone de curl.
Conclusión
La comparación se resuelve más rápido de lo que su popularidad sugiere, ya que las dos herramientas se han diseñado en torno a verbos diferentes.
curl transfiere. wget descarga. curl escribe en la salida estándar, como cat, hace exactamente lo que se le pide e informa del resto; por eso no sigue las redirecciones, no vuelve a intentarlo y necesita un parámetro para escribir un archivo. wget escribe en el disco, como cp, y todo lo que hace por defecto se deriva del objetivo de que al final quede un archivo.
Hay cuatro capacidades que determinan la elección de forma definitiva, y si tu tarea implica una de ellas, el resto de la comparación es irrelevante. La descarga recursiva y la duplicación de sitios web son exclusivas de wget: el propio mantenedor de curl las señala como el principal punto fuerte de wget, y curl no tiene equivalente. Las subidas, los proxies SOCKS y las transferencias paralelas son exclusivas de curl.
Aparte de eso, ambas herramientas funcionan, y las diferencias prácticas se reducen a la sintaxis de los parámetros y a los valores por defecto. Ten cuidado con la colisión entre «-O» al traducir comandos entre ambas, ya que significa cosas opuestas en cada una. Y en cualquier proceso automatizado, expresa tus intenciones de forma explícita en lugar de confiar en las suposiciones de cualquiera de las herramientas: «curl -sSfL --max-time 30» y «wget --tries=3 --timeout=30» son dos comandos que seguirán teniendo sentido para quien los lea el año que viene.
Sobre los proxies: los vendemos, pero la mayoría de los usos de estas herramientas no los necesitan. Cuando sí se necesite uno, la compatibilidad de curl es más amplia, y el detalle que importa más que la herramienta es utilizar socks5h:// en lugar de socks5://, para que las búsquedas de nombres de host sigan la misma ruta que tu tráfico.
La recomendación sincera es instalar ambos. Son pequeños, son gratuitos y la discusión sobre cuál es mejor quedó zanjada hace años por el hecho de que la mayoría de los equipos en funcionamiento tienen ambos.