Nushell, la shell que entiende datos y tu IA

Vistas: 0
0:00 / 0:00
Nushell, la shell que entiende datos y tu IA

Hace algún tiempo, en estos episodios os hablé de mi salto de Bash a Fish. Recuerdo perfectamente la sensación: el autocompletado, el resaltado de sintaxis, los atajos de teclado… todo era tan moderno. Fish me ha ido de maravilla, de verdad. Pero siempre había algo que me mosqueaba, una pequeña piedra en el zapato que no terminaba de desaparecer. La cuestión es que Fish, por muy moderno que sea, sigue pensando en texto. Los pipes de Fish (como los de Bash, como los de Zsh) son tuberías de texto plano. Y el texto plano tiene sus limitaciones, sobre todo cuando trabajas con datos de verdad: un JSON que te devuelve una API, el frontmatter YAML de tus notas Markdown, las columnas de un CSV con los datos de tu proyecto. Entonces descubrí Nushell. Y te juro que fue como cuando pasas de usar cat a usar bat, o de find a fd. Esa sensación de que esto es lo que tendría que haber sido siempre se apodera de ti.

Pero antes de seguir, tengo que hacer una mención especial. Hace tiempo, José Jiménez me habló de Nushell. Ya por aquella época había trasteado un poco con ella, pero la dejé de lado. Me quedé con Fish, las cosas como son. Pues bien, José, si estás leyendo esto: tardé, pero llegué. Porque Nushell ha vuelto a mi radar con fuerza, y esta vez para quedarse.

La promesa del episodio de hoy es clara: al terminar este artículo vas a saber qué hace diferente a Nushell, vas a ver con tus propios ojos cómo procesar datos reales (tus notas Markdown, un JSON de una API, lo que sea) y vas a conectar Nushell con Ollama para crear pipelines de IA locales sin tener que escribir ni una línea de Python. Así que si alguna vez has pensado que los pipes de Unix se habían quedado un poco anticuados, y créeme que yo llevo años defendiéndolos, quédate que esto te va a interesar.

El problema del texto plano

Vamos a ponernos en situación. Imagina que tienes un directorio con un montón de archivos y quieres listar los que pesan más de un megabyte, ordenados por tamaño. En Bash harías algo así:

ls -la | awk '$5 > 1048576 {print $5, $9}' | sort -rn

Fíjate en lo que está pasando aquí. Awk. $5. 1048576. Necesitas saber que el tamaño es la quinta columna, que el nombre es la novena, que el tamaño en bytes es un número enorme que tienes que calcular mentalmente… Y si alguien cambia el formato de ls (que conste que en scripts no deberías parsear ls, pero todo el mundo lo hace) todo se rompe. Es frágil, es críptico, y sobre todo, es texto.

En Nushell, el mismo ejemplo es:

ls | where size > 1mb | sort-by size

Y te juro que no tiene más misterio. size es una columna de verdad, con tipo filesize. 1mb es un literal de tamaño que se entiende solo. where es un filtro de tablas. sort-by ordena por columna. No hay columnas posicionales, no hay parseo manual, no hay awk. Es como si tu terminal entendiera SQL de repente.

Pero esto solo es la punta del iceberg. Vamos a profundizar.

Tipos nativos: la shell entiende lo que manejas

Cuando digo que Nushell entiende tipos, no estoy exagerando. Te pongo más ejemplos para que lo veas claro:

# En Nu, esto son tipos de verdad, no strings
ls | where type == file       # type es string 'file' o 'dir'
ls | where size > 10kb        # size es filesize, 10kb es un literal
ps | where cpu > 50.0         # cpu es float
date now | date humanize      # date es... date

En Bash todo es texto. ls -la te devuelve texto, ps aux te devuelve texto, y parseas con awk, sed, cut… en Nushell cada comando devuelve datos con tipos. Cuando haces ps en Nushell, obtienes una tabla con columnas tipadas: pid como entero, name como string, cpu como float, mem como filesize. No tienes que adivinar qué columna es cuál porque todo tiene nombre y tipo.

Te puedo asegurar que cuando llevas veinte años escribiendo ps aux | awk '{print $2}' y de repente escribes ps | get pid, sientes que te han quitado un peso de encima. Es como si la shell por fin hablara tu mismo idioma.

La trifecta: ls, where y select

Vale, vamos a ensuciarnos las manos. Abro un terminal con Nu y escribo ls. ¿Qué pasa? Pues que veo una tabla. Con columnas: name, type, size, modified. Ordenaditas. Sin colores locos ni texto sin formato. Es una tabla de verdad, de esas que podrías cargar en una hoja de cálculo.

Ahora filtro:

ls | where type == file | sort-by size

Archivos, ordenados por tamaño. Si quiero solo los nombres y tamaños:

ls | where type == file | sort-by size | select name size

Esto es lo que se llama pensar en columnas. No estás manipulando texto, estás manipulando tablas. Y lo mejor de todo es que el autocompletado de Nu te sugiere los nombres de las columnas cuando escribes select. Es una experiencia tan satisfactoria que no quieres volver atrás.

get vs select: la confusión más común

Aquí hay una trampa que a mí me costó pillar. get y select parecen lo mismo, pero no lo son. Verás:

# select devuelve una tabla con las columnas elegidas
ls | select name
# → una tabla con una columna 'name'

# get devuelve los valores
ls | get name
# → una lista: "file1.rs", "file2.rs", ...

select mantiene la estructura de tabla. get extrae los valores. ¿Quieres seguir filtrando la tabla? Usa select. ¿Quieres trabajar con los nombres como lista para iterar? Usa get. Es una distinción sutil pero importantísima que te ahorrará más de un quebradero de cabeza.

open: el comando que lo entiende todo

Y luego está open. En Bash abres archivos con cat. En Nu usas open. Pero open no lee archivos: entiende archivos. Es como si cada archivo llevara un letrero diciendo lo que es.

open package.json
# → tabla con columnas: name, version, dependencies...

open package.json | get version
# → "1.0.0"

open data.csv
# → tabla con las columnas del CSV

open config.yaml
# → tabla con las claves del YAML

Nu detecta el formato por la extensión. Y si no, porque a veces tienes un .md con frontmatter YAML, siempre puedes forzar el parseo con from yaml, from json, from csv

Y ahora viene el momento de ser honesto con vosotros. No tiro piedras contra jq (de hecho le dedicamos un episodio entero en su momento) pero cuando ya estás dentro de Nushell, muchas veces no hace falta. open lo hace todo. Que no, que no os digo que desinstaléis jq, ojo. Es que con Nu ya no lo necesitas para esto.

SQLite desde la shell, sin drivers ni ORM

Y ya puestos, ¿sabéis que open también entiende SQLite?

# Abrir base de datos y ver tablas
open knowledge.db

# Ejecutar SQL directamente
open knowledge.db | query db "SELECT * FROM nodes WHERE type = 'function' LIMIT 10"

# JOINs desde la shell
open knowledge.db | query db "
SELECT n.name, n.type, n.file, e.edge_type
FROM nodes n
JOIN edges e ON n.id = e.source_id
ORDER BY n.name
"

Abres una base de datos SQLite como quien abre un archivo de texto. Y ejecutas SQL directamente. Sin drivers, sin ORM, sin Python. Solo el shell. Esto a mí me voló la cabeza la primera vez que lo vi.

Y lo mejor: puedes combinar todo. http get algo, mezclarlo con datos de una base de datos SQLite, filtrar con where, guardar con save… todo en una línea, sin scripts, sin archivos temporales.

$in y save: el pipeline de tres partes

Una de las cosas que más me flipan de Nu es la variable $in. Es como el $_ de Bash pero muchísimo más potente.

# Crear un directorio con la fecha actual
date now | format date '%F' | $"($in) Report" | mkdir $in
# → crea "2026-08-27 Report"

$in captura lo que viene por el pipe. Y como los strings se pueden interpolar con $"($in)...", tienes un pipeline de tres partes: entrada → filtro → salida. Es como tener un mini-lenguaje de transformación de datos en el propio shell.

Y luego está el tema de save en lugar de >. En Nu, redirigir con > no funciona como en Bash — porque > en Nu es el operador «mayor que», no «redirigir».

# Bash: echo "hola" > fichero.txt
# Nu:   "hola" | save fichero.txt

# Añadir al final:
"otra línea" | save --append fichero.txt

Es diferente, lo sé. Pero una vez que te acostumbras, tiene mucho más sentido. Sobre todo porque save puede guardar tablas completas en CSV, JSON, YAML… piensa en ello: ls | where type == file | select name size | to json | save ficheros.json. En una línea tienes un inventario de tus archivos en JSON.

Parsear frontmatter YAML de notas Markdown

Aquí viene una de las cosas que más me ha volado la cabeza. Tengo un montón de notas Markdown con frontmatter YAML — título, tags, fecha… — y quiero extraer todas las notas que tengan el tag «linux». En Bash esto es un drama. En Nushell…

# Extraer frontmatter de una nota individual
open nota.md --raw
| lines
| first 10
| str join "\n"
| parse "---{yaml}---"
| get yaml.0
| from yaml
| get title

parse con esa sintaxis de llaves extrae todo lo que hay entre los ---. from yaml convierte ese bloque en una estructura de datos. Y get title me da el título. Es como tener un parser de YAML en el propio prompt.

Y la guinda del pastel: si quieres hacerlo con todas las notas a la vez, en paralelo:

ls **/*.md
| par-each { |f|
    open $f.name --raw
    | lines | first 10 | str join "\n"
    | parse "---{yaml}---"
    | get yaml.0
    | from yaml
    | select title tags date
}
| flatten

Fíjate en par-each. Eso ejecuta en paralelo. Si tienes 200 notas, las procesa con varios hilos a la vez. En Bash tendrías que montar un script con xargs -P y estar rezando para que funcionara bien.

Y lo mejor es que puedes filtrar después. Añade un where tags =~ "linux" al final del pipeline y tienes solo las notas que te interesan. Sin scripts, sin Python, sin nada.

http get: olvídate de curl | jq

Y luego está el acceso a APIs. En Bash harías curl https://api.github.com/... | jq '.login,.contributions'. En Nu:

http get https://api.github.com/repos/nushell/nushell/contributors
| select login contributions

Directamente una tabla. Con columnas login y contributions. Sin curl, sin parseo manual. Y sin jq — no hace falta, Nushell ya entiende el JSON de la respuesta. Aunque bueno, ya sabéis que a jq le tenemos cariño por aquí, es que con Nu es innecesario.

Otro ejemplo: el tiempo en Madrid:

http get "https://api.open-meteo.com/v1/forecast?latitude=40.42&longitude=-3.70&daily=temperature_2m_max&timezone=Europe/Madrid"
| get daily
| select time temperature_2m_max

Y te devuelve una tabla con las fechas y las temperaturas máximas. Sin salir del shell.

Procesar datos reales: análisis de CSV y JSON

Vale, hasta aquí todo son ejemplos sueltos. Vamos a ver un caso de uso completo. Imagina que tienes un archivo CSV con datos de personas: nombre, edad, ciudad, si están activas o no. Algo así:

nombre,edad,ciudad,activo
Ana García,32,Madrid,true
Carlos López,28,Barcelona,true
Elena Martín,45,Valencia,false
David Ruiz,37,Sevilla,true

Con Nushell, abres el CSV y ya tienes una tabla tipada. A partir de ahí, el cielo es el límite:

# Personas mayores de 30 años
open datos.csv | where edad > 30 | select nombre edad ciudad

# Media de edad de todas las personas
open datos.csv | get edad | math avg

# Personas activas
open datos.csv | where activo == true | select nombre edad ciudad

# Agrupar por ciudad y contar
open datos.csv | group-by ciudad --to-table
| each { |row| { ciudad: $row.ciudad, total: ($row.grupo | length) } }

En Bash esto serían tuberías de awk, sort, uniq -c, grep… y estarías rezando para que las columnas no se descolocaran. En Nu son cuatro comandos que se leen solos.

Y lo mismo con JSON. Imagina que tienes un JSON de productos:

[
  {"id": 1, "nombre": "Portátil Pro", "precio": 1200, "stock": 15},
  {"id": 2, "nombre": "Monitor 27\"", "precio": 350, "stock": 42},
  {"id": 3, "nombre": "Teclado Mecánico", "precio": 120, "stock": 8}
]

En Nushell:

# Abrir y ver productos con stock bajo
open productos.json | where stock < 10 | select nombre stock

# Precio medio de todos los productos
open productos.json | get precio | math avg

# Productos ordenados por precio descendente
open productos.json | sort-by precio --reverse | select nombre precio

Sin jq, sin Python, sin nada. Solo el shell y sus tipos nativos. Y si quieres guardar el resultado, añades | save productos_bajo_stock.json al final. Así de simple.

Comparativa: Bash vs Zsh vs Fish vs Nushell

Vale, vamos a hacer una comparativa rápida porque sé que muchos estáis pensando: «vale, pero yo con Fish voy bien». Te entiendo. A mí Fish me encanta. Pero vamos a ver las diferencias claras.

Bash es el abuelo. Funciona en cualquier sitio, tienes scripts de 40 años que siguen funcionando. Pero el manejo de datos es arcaico. Todo es texto, [ cond ] es un infierno, y los arrays son un chiste malo. Yo empecé con Bash y Bashit, y durante años me defendí con awk y sed. Pero siempre tenía la sensación de que estaba peleándome con la shell en lugar de colaborar con ella.

Zsh es Bash con esteroides. Oh-my-zsh, powerlevel10k, autocompletados mejores. Pero en el fondo, los pipes siguen siendo texto. Zsh no entiende de tipos. Cuando pasé a Zsh con Oh-my-zsh, recuerdo que me sentí muy moderno. Los temas, los plugins, el autocompletado inteligente… pero con el tiempo me di cuenta de que para procesar datos seguía usando las mismas herramientas de siempre. Zsh me daba una experiencia más bonita, pero no resolvía el problema de fondo.

Fish es moderno, intuitivo, y el autocompletado es el mejor de todos los shells tradicionales. Pero Fish sigue siendo texto. Puedes tener ls | grep algo y seguir parseando con awk. Fish no sabe qué es un filesize o una fecha. Cuando descubrí Fish, pensé que había encontrado el shell definitivo. Y lo fue durante un tiempo. El autocompletado predictivo, el resaltado de sintaxis, los atajos de teclado… todo era genial. Pero llegó un punto en el que empecé a trabajar más con datos — JSON de APIs, YAML de configuraciones, CSV de análisis — y me di cuenta de que Fish se quedaba corto. No es culpa de Fish, ojo. Fish hace lo que promete, y lo hace bien. Es que el paradigma del texto plano tiene un techo.

Nushell es el único que entiende estructuras de datos. ls devuelve una tabla, no texto. Puedes hacer where size > 1mb en lugar de ls -la | awk '$5 > 1048576'. Y entiende JSON, YAML, TOML, SQLite de forma nativa.

Mira esta comparativa rápida:

ConceptoBashNushell
TuberíasTexto plano → grep/awk/sedEstructuras → where/select/get
Redirigirecho "x" > file.txt"x" | save file.txt
Variables$VAR mutables siempre$var inmutables por defecto
if[ cond ] (con test)if cond { ... } (como Rust)
JSONCon jqNativo con from json
TipadoTodo es stringint, float, string, date, filesize…

Y luego hay cosas que en Nu directamente no existen. Como eval. Nu no tiene eval por diseño. Porque Nu compila el código en dos fases, y permitir eval rompería todo. Si necesitas ejecutar código generado dinámicamente, lanzas otro proceso nu -c "...".

¿Y PowerShell?

«Pero Lorenzo, PowerShell también pasa objetos entre comandos». Y tienes razón. PowerShell fue el primero en hacer tuberías con objetos. El problema de PowerShell es que es verboso hasta decir basta. Get-ChildItem, Where-Object, Select-Object… y está atado a .NET. Nu es mucho más conciso — ls, where, select — y está escrito en Rust, que arranca al instante. Sin runtime, sin JIT, sin esperas.

Nu es lo que PowerShell debería haber sido si lo hubieran hecho en los 2020 y no en los 2000.

Mi experiencia personal con la evolución de shells

Si tengo que ser sincero, cada salto de shell me ha costado. De Bash a Zsh fue fácil porque Zsh es compatible con Bash. De Zsh a Fish fue más duro porque la sintaxis cambia, pero el autocompletado me compensó. De Fish a Nushell… ese ha sido el salto más grande. Porque no solo cambia la sintaxis, cambia la forma de pensar. Ya no piensas en términos de «texto que pasa por un pipe», piensas en términos de «datos que fluyen por un pipeline». Es un cambio de paradigma, y como todo cambio de paradigma, cuesta.

Pero merece la pena. Te lo digo con conocimiento de causa. Llevo semanas usando Nushell como shell secundario — lo abro en una terminal aparte para hacer tareas de datos — y cada vez que lo uso, descubro algo nuevo que me hace sonreír. Es como cuando aprendes un nuevo lenguaje de programación y de repente entiendes un concepto que llevabas años usando mal.

Nushell + Ollama: el momento IA

Y aquí llegamos a la parte que más me gusta. Como Nushell entiende JSON de forma nativa, y Ollama habla JSON… los dos se entienden a la perfección. Ya vimos en su momento cómo usar Ollama desde la terminal — de hecho le dedicamos un episodio entero — pero hoy lo que me interesa es cómo Nushell lo integra a nivel de datos. No necesitas Python, no necesitas scripts de 50 líneas para hacer una consulta a un modelo local.

Mira qué fácil es preguntarle a Llama directamente desde la shell:

{
    model: "llama3.2"
    prompt: "Explica qué es Nushell en una frase"
    stream: false
} | to json | http post http://localhost:11434/api/generate $in | get response

Creamos un objeto con {}, lo pasamos a JSON con to json, hacemos un POST con http post, y extraemos la respuesta con get response. Cuatro comandos. Sin Python, sin curl, sin nada.

Y como los datos son estructurados, puedes hacer cosas mucho más potentes.

Pipeline killer: ps → Ollama → kill

Mi ejemplo favorito de todo el episodio. Imagina que tienes un proceso que se está comiendo toda la RAM. Quieres que la IA te diga cuál matar.

# Pipeline completo: listar procesos, preguntar a IA cuál matar
ps | where mem > 100mb | to json | http post http://localhost:11434/api/generate {
    model: "llama3.2"
    prompt: $"Dado este JSON de procesos, dime solo el PID del que más memoria consume: ($in)"
    stream: false
} | get response | parse --regex '\b(\d+)\b' | get capture0.0 | kill $in

Estamos cogiendo los procesos con ps, filtrando los que usan más de 100MB de RAM con where mem > 100mb, pasando eso a JSON, mandándoselo a Ollama, pidiéndole que nos diga el PID del que más consume, parseando la respuesta para sacar el PID, y matando el proceso con kill. Todo en una línea.

Esto no es un truco de salón. Esto es un flujo de trabajo real que puedes poner en producción. La shell ya no es solo un intérprete de comandos, se convierte en un asistente que entiende el contexto de tu sistema.

Extraer metadatos de la respuesta de Ollama

Y ya que estamos, una cosa interesante: la respuesta de Ollama no solo contiene el texto generado. También incluye metadatos como el tiempo de generación, los tokens usados, el modelo… Puedes acceder a todo eso porque, como Nushell entiende JSON, tienes la respuesta completa como estructura de datos:

let respuesta = ({
    model: "llama3.2"
    prompt: "Dime solo la palabra 'Nushell'"
    stream: false
} | to json | http post http://localhost:11434/api/generate $in)

# Ver todos los campos disponibles
$respuesta | columns

# Tiempo total de generación
$respuesta | get total_duration | into duration | format duration '.3s'

# Tokens generados
$respuesta | get eval_count

Puedes hacer estadísticas de tus consultas, medir tiempos, comparar modelos… todo desde el shell. Sin salir de la terminal.

ai.nu: el módulo que lo envuelve todo

Y si no quieres hacer los HTTP posts manualmente, existe ai.nu, un módulo nativo de Nushell que envuelve las APIs de Ollama, OpenAI y DeepSeek. La instalación es sencilla:

git clone --depth=1 https://github.com/fj0r/ai.nu.git ~/nu_libs/ai.nu

Luego añades a tu env.nu:

$env.NU_LIB_DIRS ++= glob ~/nu_libs/*

Y a tu config.nu:

use ai *

Y entonces puedes hacer cosas como esta:

# Consulta sencilla a Ollama (por defecto)
"what is nushell" | ai-do general en

El caso de uso que más me mola: generar mensajes de commit automáticos a partir del diff:

git diff | ai-do git-diff-summary en | git commit -m $in

Coges el diff de git, se lo mandas a la IA, y te genera un mensaje de commit descriptivo. Y lo metes directamente en git commit -m. Automatización pura.

Y lo mejor: puedes configurar varios proveedores. Tienes Ollama por defecto para lo local, pero si quieres usar DeepSeek o GPT-4 para cosas más complejas, lo añades con ai-config-upsert-provider y alternas entre ellos según la tarea.

Function calling desde Nushell

Y una cosa que me ha dejado loco: function calling. Puedes pedirle a la IA que llame a funciones de Nushell.

"Will it rain tomorrow? I'm in San Francisco."
| ai-do general en -f [get_current_weather] -m llama3.2
| to yaml

La IA entiende que necesita llamar a get_current_weather con el parámetro "San Francisco, CA" y te devuelve la llamada a la función estructurada. Esto es el futuro de la shell: no solo ejecutas comandos, la IA los ejecuta por ti.

Imagina las posibilidades. Tienes una función en Nushell que consulta una API de Docker, otra que analiza logs, otra que envía notificaciones… y le pides a la IA en lenguaje natural que orqueste todo. Sin scripts, sin programación. Solo lenguaje natural y pipelines de datos.

MCP: el protocolo que conecta la IA con el shell

Y aquí viene una de las novedades más interesantes. Desde la versión v0.108.0 (octubre de 2025), Nushell incluye un servidor MCP opcional. MCP son las siglas de Model Context Protocol, un protocolo estándar que permite a agentes de IA interactuar con herramientas de forma nativa. Nushell es el primer shell que incorpora soporte nativo para MCP.

¿Qué significa esto en la práctica? Pues que un agente de IA — ya sea Ollama, Claude, o cualquier otro que soporte MCP — puede conectarse directamente a tu shell, ejecutar comandos, leer archivos, analizar datos… todo a través de un protocolo estándar. No necesitas wrappers, no necesitas scripts de integración, no necesitas nada. El shell habla el mismo idioma que la IA.

Esto convierte a Nushell en algo más que un shell: es una plataforma de integración entre tu sistema y los modelos de lenguaje. Y esto, créeme, es solo el principio.

Casos de uso reales donde Nushell brilla

Antes de cerrar, quiero dejarte con algunos casos de uso reales donde Nushell marca la diferencia:

DevOps: procesar logs JSON, consultar APIs de Docker o Kubernetes, orquestar contenedores. Todo con el mismo shell, sin herramientas externas. Por ejemplo, para analizar los logs de Docker en formato JSON:

# Analizar logs de Docker (asumiendo que los tienes en JSON)
open docker-logs.json
| where level == "error"
| select timestamp message service
| first 20

Análisis de datos: open file.csv | where columna > 5 | math avg y ya tienes la media de una columna. Sin R, sin Python, sin pandas. Puedes hacer desde medias simples hasta desviaciones estándar con math stddev. Y si necesitas agrupar, group-by te da las agrupaciones al instante:

# Análisis completo de un CSV
open ventas.csv
| group-by producto --to-table
| each { |row|
    {
        producto: $row.producto
        total_ventas: ($row.grupo | length)
        importe_total: ($row.grupo | get importe | math sum)
        importe_medio: ($row.grupo | get importe | math avg)
    }
}
| sort-by importe_total --reverse

Git workflows: analizar commits, generar changelogs, automatizar releases con pipelines de datos. Los contribuidores de un repo en GitHub los consultas directamente:

http get https://api.github.com/repos/nushell/nushell/contributors
| select login contributions

Gestión de notas: buscar, filtrar y transformar frontmatter YAML de cientos de notas Markdown en paralelo. Justo lo que os enseñaba antes con par-each. En mi caso, tengo más de 300 notas en Markdown con frontmatter, y poder extraer todas las que tienen un tag concreto en una línea de shell es algo que antes requería un script de Python.

Automatización del sistema: combinar ps, df, sys con where y select para obtener informes del sistema al instante:

# Procesos que más CPU consumen (top 5)
ps | sort-by cpu | reverse | first 5 | select pid name cpu mem

# Uso de disco en formato legible
df | where mount != "none" | select mount size used free

# Información del sistema
sys | get host | select name os_version uptime

Menos jq: si usas jq a diario, Nushell te va a parecer un sueño. Que conste que aquí no estamos en contra de jq — ya sabéis que le dedicamos un episodio entero — pero para muchas tareas la sintaxis de Nu es mucho más natural. Es otra herramienta más en el cinturón.

Limitaciones que hay que conocer con honestidad

Ahora bien, no todo es perfecto. Vamos con las limitaciones, que también las hay y es mejor saberlo de entrada.

Primero: no tiene eval. Si vienes de Bash y usas eval para ejecutar código generado dinámicamente, en Nu no puedes. Hay que usar nu -c "..." en un proceso separado. Es por seguridad y porque Nu compila en dos fases, pero oye, es una limitación real.

Segundo: los scripts Bash no son compatibles. No puedes copiar-pegar un script de Bash y esperar que funcione. Hay que reescribirlo. La sintaxis de if, de for, de variables, de pipes… todo es diferente. Si tienes una colección enorme de scripts Bash, migrarlos no va a ser trivial.

Tercero: el ecosistema es más pequeño. Fish tiene toneladas de plugins, Zsh tiene Oh-my-zsh, Bash tiene scripts de los 80. Nu tiene una comunidad que crece rápido — más de 40.000 estrellas en GitHub y 600+ contribuidores — pero todavía no tiene el mismo volumen de plugins y scripts.

Cuarto: sigue en versión 0.x. La versión actual es la v0.115.1 (agosto de 2026). El propio README del proyecto dice que muchos lo usan a diario, pero que puede haber inestabilidad en algunos comandos. No es un shell para producción en servidores remotos — ahí seguramente solo tengas Bash.

Y quinto: la curva de aprendizaje. Hay que «pensar en Nu». Cuando llevas 20 años escribiendo ls -la | awk '{print $9}', cambiar a ls | select name cuesta. Pero una vez que lo haces… no quieres volver.

Consejos prácticos para empezar con Nushell

Si después de todo esto te ha picado la curiosidad, aquí van mis consejos para que la transición no sea frustrante:

No intentes migrar de golpe. Usa Nu como shell de exploración. Abre un terminal con nu y juega. Haz ls, prueba where, experimenta con open. Cuando necesites hacer algo con datos — un CSV, un JSON, una consulta a una API — abre Nu y hazlo ahí. Poco a poco.

Aprende los comandos clave primero. Céntrate en ls, where, select, get, open, save. Con esos seis comandos ya puedes hacer el 80% de las tareas del día a día. Luego añades par-each, http get, from json, to json, y ya tienes el 95%.

Usa el autocompletado. Una de las mejores cosas de Nu es que el autocompletado te sugiere los nombres de las columnas. Cuando escribes select y pulsas tab, te aparecen las columnas disponibles. Es una forma estupenda de explorar los datos sin tener que memorizar nada.

Ten Bash como respaldo. No elimines Bash de tu sistema. Yo tengo Fish como shell por defecto, pero abro nu cuando necesito trabajar con datos. Y si algo no funciona en Nu, siempre puedo caer en Bash. No hay vergüenza en eso.

Empieza con scripts pequeños. Cuando te sientas cómodo con los comandos, escribe tu primer script Nu. Algo sencillo: un script que lea un CSV, filtre unas filas, y guarde el resultado. Luego ve aumentando la complejidad.

Mira el Cookbook oficial. La documentación de Nushell tiene una sección de cookbook con ejemplos prácticos: cómo procesar logs, cómo analizar el historial de git, cómo hacer peticiones HTTP… Es un recurso increíble para aprender.

Únete a la comunidad. El Discord de Nushell es muy activo y la gente es muy amable. Si tienes dudas, preguntas. Y si descubres algo chulo, compártelo. La comunidad es uno de los puntos fuertes del proyecto.

Instalación

Si te ha picado la curiosidad — y espero que sí — instalar Nushell es muy fácil:

# Ubuntu/Debian (desde apt)
sudo apt install nushell

# Arch Linux
sudo pacman -S nushell

# macOS
brew install nushell

# O con cargo (Rust)
cargo install nu --locked

# Docker
docker run -it --rm ghcr.io/nushell/nushell:latest-alpine

Luego ejecutas nu y ya estás dentro. Puedes probar comandos, hacer ls, ps, where, select… y si te gusta, lo pones como shell por defecto con chsh -s $(which nu).

Mi recomendación: no intentes migrar todo de golpe. Usa Nu como shell de exploración. Abre un terminal con nu, prueba los comandos, juega con open, prueba where, haz un http get a una API pública. Y cuando te sientas cómodo, empieza a escribir scripts.

Porque al final, un shell es solo una herramienta. Y la mejor herramienta es la que entiende cómo trabajas tú. Pero si trabajas con datos — y hoy en día todo son datos — Nushell te va a cambiar la forma de ver la terminal. Te lo digo por experiencia.


Más información

Deja una respuesta