NuShell
Sunday, 2025-11-02 Comments
Tooling built around NuShell, a modern structured shell
Previous post: GUI.
I am organising a workshop about NuShell in December 2025, more information.
Introduction
Bash scripts are difficult to write and maintain, because of old-fashioned syntax and a lack of modern features. Frequently, Bash itself does not support certain crucial programming operations.
For example, you have to crawl the web for info on how to use jq to extract a basic value from an API. It almost feels like playing “Dungeons and Dragons”.
Nushell alleviates the pains of frustrated Bash scripters:
- It has modern programming language features.
- You can still pipe as much as you want.
- Most commands stay the same.
In general you don’t need to alias commands as much in Nushell:
- Nushell has an
rmcommand that can be configured to delete files to the trash always. Don’t search for an external ‘safe-delete’rmcommand, it’s already part of Nushell core. - It also has an
lscommand that can be queried using a kind of SQL syntax with traditional pipes.
The community collects good NuShell scripts in the nu_scripts repository.
Tooling for NuShell
Currently, the tooling is lacking a bit for NuShell.
Linter
There is no real linter, so I created my own: nu-lint. It was inspired by my experience with Clippy (a Rust linter). Please try it out and report any bugs in the issue tracker, thanks!
Configuration extensions
Audio notifications
Do you start long-running commands and forget to follow-up on them? The visual / audio bell of konsole was not so reliable for me. Instead, I figured out a way to do it within Nushell.
You can define a function in your Nushell config at ~/.config/nushell/config.nu and add it as pre_prompt hook:
Click to show Nu shell snippet for audio notifications
```bash def notify-long-command [] { const NOTIFICATION_THRESHOLD = 30sec const SOUND_FILE = "/run/current-system/sw/share/sounds/freedesktop/stereo/bell.oga"let cmd_duration = (($env.CMD_DURATION_MS? | default “0”) | into int | into duration -u ms)
if $cmd_duration > $NOTIFICATION_THRESHOLD { try { ^pw-play $SOUND_FILE } catch { ^paplay $SOUND_FILE } } }
$env.config = ( $env.config | merge { hooks: { pre_prompt: [ {|| notify-long-command } ] } } )
</details>
Notice that Nushell has a 'duration' type like Rust. Tweak the parameters as you wish. Maybe you can find out a way to modify the sound based on metadata about the previous command?