Skip to main content

Nushell

Nushell

Antes de sumergirnos en Nushell, es importante contextualizar mi experiencia previa. Durante mucho tiempo, Zsh ha sido mi shell predeterminado, atendiendo excepcionalmente bien a mis necesidades, especialmente cuando se combina con Oh My Zsh y algunos plugins cuidadosamente seleccionados. Si tienes curiosidad sobre cómo optimicé mi entorno Zsh, te recomiendo consultar el artículo Potenciando el Shell. Dicho esto, para que el cambio a Nushell sea justificable, necesita no solo igualar, sino superar significativamente las expectativas establecidas por Zsh.

Proyecto en Github

Documentación oficial

En 2022, mi búsqueda de mayor productividad en la terminal me llevó a Nushell. Aunque inicialmente entusiasmado, decidí posponer la transición, ya que el proyecto aún no había alcanzado la versión 1.0. Ahora, en 2025, con Nushell demostrando madurez significativa, ha llegado el momento de integrarlo en mi flujo de trabajo profesional.

Instalación

No vamos a reinventar la rueda, consulta instalación en la documentación oficial e instala de la forma que mejor te convenga.

brew install nushell

nu --version
0.101.0

nu

Abre tu terminal, escribe nu y ya estaremos dentro de él.

Concepto

Nushell (o simplemente "nu") es un shell moderno, desarrollado en Rust, que ofrece un enfoque innovador en comparación con shells tradicionales como Bash o Zsh.

Su diferencial está en el enfoque en la gestión y manipulación de datos estructurados, proporcionando una presentación más refinada e intuitiva de los resultados.

Para ilustrar las capacidades de Nushell, comencemos con un ejemplo simple: el comando ls. Este comando básico, que lista archivos y directorios, sirve como una excelente demostración inicial. Para una comparación directa, abrí dos terminales lado a lado: a la izquierda, mi familiar Zsh, y a la derecha, Nushell.

alt text

A primera vista, es evidente que Nushell presenta la salida como una tabla más organizada y visualmente atractiva. Sin embargo, la verdadera innovación no está en la apariencia, sino en el enfoque subyacente. No sería prudente cambiar mi terminal favorito solo por cuestiones estéticas, especialmente considerando que ZSH ofrece una variedad de plugins con beneficios significativos.

El diferencial de Nushell está en su capacidad de procesar datos estructurados nativamente, como tablas, JSON, YAML y XML, en contraste con los shells tradicionales que tratan todo como texto plano. Esta característica facilita enormemente la manipulación y filtrado de datos.

Para apreciar plenamente el poder de este enfoque, es importante primero comprender cómo opera un shell clásico. Los usuarios intermedios ya están familiarizados con el concepto de Pipes, que esencialmente consiste en dirigir la salida de un comando como entrada para otro.

Por ejemplo en Zsh si quisiéramos mostrar solo los archivos .json haríamos

ls | egrep .json
package-lock.json
package.json
tsconfig.json

Hicimos que la salida del comando ls con todos los archivos sea la entrada de egrep y este mostrará solamente aquellos que poseen .json.

Podríamos continuar inyectando la salida de un comando como el input de otro comando y más otro hasta llegar al resultado que queremos.

¡Sé que podemos hacer esto de otras maneras, pero lo que importa es el concepto!

ls | egrep .json | grep package
package-lock.json
package.json

Nushell revoluciona el concepto de shell, pues su salida no se limita a mero texto en la consola, sino que consiste en datos estructurados, lo que transforma completamente el escenario de uso. La tabla elegante que observamos anteriormente tiene un valor mucho más allá de su presentación estética; su verdadera importancia reside en la estructura subyacente de los datos.

En Nushell, la canalización (Pipes) ofrece posibilidades más amplias de manipulación, con diversos comandos a disposición. Un ejemplo notable es | where, que permite iniciar procesos de filtrado sofisticados. Para explorar las potencialidades de este sistema, podemos utilizar la flag --help y descubrir una gama de opciones disponibles para manipulación de datos.

ls | where --help
Filter values based on a row condition.

This command works similar to 'filter' but allows extra shorthands for working with
tables, known as "row conditions". On the other hand, reading the condition from a variable is
not supported.

Search terms: filter, find, search, condition

Usage:
> where <row_condition>

Flags:
-h, --help: Display the help message for this command

Parameters:
row_condition <condition>: Filter condition.

Examples:
Filter rows of a table according to a condition
> [{a: 1} {a: 2}] | where a > 1
╭───┬───╮
# │ a │
├───┼───┤
02
╰───┴───╯

Filter items of a list according to a condition
> [1 2] | where {|x| $x > 1}
╭───┬───╮
02
╰───┴───╯

List all files in the current directory with sizes greater than 2kb
> ls | where size > 2kb

List only the files in the current directory
> ls | where type == file

List all files with names that contain "Car"
> ls | where name =~ "Car"

List all files that were modified in the last two weeks
> ls | where modified >= (date now) - 2wk

Find files whose filenames don't begin with the correct sequential number
> ls | where type == file | sort-by name --natural | enumerate | where {|e| $e.item.name !~ $'^($e.index + 1)' } | each {|| get item }

Find case-insensitively files called "readme", without an explicit closure
> ls | where ($it.name | str downcase) =~ readme

same as above but with regex only
> ls | where name =~ '(?i)readme'

Ahora vamos a revisar nuevamente nuestra tabla con el comando ls -l para ver más detalles.

alt text

Las columnas muestran lo que podemos filtrar entonces vamos directo al comando...

alt text

Lo que hicimos hasta ahora puede no parecer suficiente para justificar un cambio cultural, especialmente considerando nuestra familiaridad con comandos existentes, algunos de los cuales ya tenemos atajos y ejecutamos con gran rapidez. Sin embargo, es importante ponderar si este cambio realmente vale la pena.

Al reflexionar, podemos destacar algunos puntos importantes:

  • La documentación de ayuda en Nushell es significativamente más completa y bien estructurada.
  • La necesidad de memorizar argumentos específicos se reduce, ya que la mayoría de las operaciones puede realizarse canalizando los datos a comandos como | where y otras instrucciones similares.

El aspecto fundamental a comprender es que, a diferencia de los shells tradicionales que invariablemente producen texto como salida, Nushell genera datos estructurados. Estos datos pueden originarse de prácticamente cualquier formato, y Nushell los convierte a su propio formato interno. Esta característica permite que la salida de un comando sea fácilmente utilizada como entrada para otros comandos a través de pipes, creando un flujo de trabajo más cohesivo y poderoso.

La ventaja de Nushell es que logra transformar entradas de texto en datos estructurados.

Si fuéramos a hacer el comando anterior para filtrar por los archivos (no carpetas) menores que 1kb.

alt text

Hacer ese comando con un shell clásico implicaría conocer otros comandos, como por ejemplo find, pues si fuera a hacer con ls sería mucho más trabajoso.

Sería algo como el comando abajo:

# Vea el nivel de conocimiento necesario que se requiere
find . -maxdepth 1 -type f -size -1024c -exec basename {} \;
README.md
package.json
tsconfig.json

Nushell vs Posix

Nushell, al ser un shell no-POSIX, presenta algunas diferencias importantes en relación a Zsh y otros shells que vale la pena considerar.

Nushell posee su propio lenguaje de script con extensión .nu, sobre el cual hablaremos más adelante. La principal diferencia es que no ejecuta scripts shell tradicionales (.sh) directamente, por no ser POSIX-compliant y debido a la forma como las salidas son generadas.

Por el momento, no estoy interesado, ni es oportuno, reemplazar completamente los scripts Bash por Nushell. No deseo reescribir todos los scripts que utilizamos en el trabajo, y esto no es necesario.

Primeramente, debemos aprender a utilizar y conocer el poder de Nushell para, posteriormente, considerar la creación de scripts específicos para él. Vamos a caminar antes de correr.

La propuesta es considerar el uso de Nushell en nuestro día a día como shell predeterminado, que se carga cuando se abre la terminal, manteniendo Bash y Zsh para desarrollar y probar nuestros Shell Scripts existentes, que todavía tienen mucha vida por delante.

Incluso utilizando Nushell podemos llamar a cualquier script desarrollado en Bash ya que el #!/bin/bash apunta quién será el ejecutor del script.

Por ejemplo el siguiente script desarrollado en bash.

#!/bin/bash
echo "¡Bienvenido! ¿Qué quieres hacer?"
echo "1. Listar archivos"
echo "2. Listar variables de ambiente en bash"
echo "3. Ver espacio en disco"


read -p "Ingresa tu elección (1-3): " opcion

case $opcion in
1)
ls -la
;;
2)
env
;;
3)
df -h
;;
*)
echo "¡Opción inválida!"
;;
esac

Vamos a invocarlo normalmente incluso dentro de un Nushell.

# Vea que al invocar un shell script tradicional quien está procesando es bash
~/teste> ./script.sh
¡Bienvenido! ¿Qué quieres hacer?
1. Listar archivos
2. Listar variables de ambiente en bash
3. Ver espacio en disco
Ingresa tu elección (1-3): 1
total 48
drwxr-xr-x@ 5 davidprata staff 160 10 Fev 08:18 .
drwxr-x---+ 67 davidprata staff 2144 10 Fev 08:51 ..
-rw-r--r--@ 1 davidprata staff 1319 14 Jan 10:36 otel.crt
-rw-r--r--@ 1 davidprata staff 15202 13 Jan 14:31 pod.yaml
-rwxr-xr-x@ 1 davidprata staff 337 10 Fev 08:18 script.sh

¡No tendremos ningún problema en el uso diario!

Observe que las salidas son equivalentes al shell que ejecutó el script, en este caso Bash. Consecuentemente, el comando ls -la produjo la salida de texto estándar característica de Bash.

Al desarrollar un script .nu, si es necesario ejecutar un comando de shell clásico de Bash dentro del script Nushell, basta utilizar la sintaxis bash -c "comando".

Abordaremos los scripts Nu más detalladamente en un momento posterior. Por ahora, consideré relevante aclarar esta duda, pues puede surgir frecuentemente durante la transición a Nushell.