A Nu-er Shell
Take a look at Nushell
ZOOOOOOM!
Is everything big enough and are we in dark mode?
Nushell
Go to demo
Nushell is a shell that makes use of the Nu Programming Language
- Cross-platform
- Everything is data
- Extensible
- Composition based
- Strongly typed
Data
- Traditional shells, e.g. bash, treat everything as strings
- Nushell treats input streams as data that can be transformed
- Uses the Nu Language for transforming data
- Wraps common commands into data-rich ones, e.g.
ls,open
> ls
╭───┬─────────────┬──────┬───────────┬────────────────╮
│ # │ name │ type │ size │ modified │
├───┼─────────────┼──────┼───────────┼────────────────┤
│ 0 │ config.nu │ file │ 1.000 B │ a month ago │
│ 1 │ env.nu │ file │ 4.3 KiB │ a month ago │
│ 2 │ history.txt │ file │ 193.6 KiB │ 12 minutes ago │
│ 3 │ scripts │ dir │ 256 B │ 2 months ago │
╰───┴─────────────┴──────┴───────────┴────────────────╯
Pipelines
- A functional programming technique
- Feels a bit like LINQ
- Can be chained together and composed
git log --oneline | lines | parse $template
- Lots of builtin function, e.g.
lines,parse,map,where,find,filter,each,glob,watch... and more!
File Formats
- Supports many common file formats as data
- CSV
- JSON
- YAML
- Can add support for custom formats easily
- Easily convert between simple formats
open data.csv | to json | save data.json
The Nu Language
## compose with command utilities
let contents = cat my-file.txt
print $contents
## define custom functions/commands
def "my custom command" [name:string] {
"Hello " + $name
}
## use a module
use my_module.nu
## load a source file into scope
source my_file.nu
## create an alias
alias gito = git log --oneline
Demo
Examples below
Nushell
- Supports pretty much anything available in a file
- Easily configurable -
$nu.config-path
Show my setup
Examples
const url = 'https://dummyjson.com/todos'
## This is the main method, running --help will show docs for all subcommands
def example [] {
print "Working with HTTP Data"
}
def "example get_full" [] {
http get $url --full
}
def "example filter_todos" [] {
http get $url
| get todos
| where completed == false
| select id todo userId
| to yaml
}
let template = '{ip} - - [{date}] "{method} {url} {protocol}" {status} {size} "{served}" "{useragent}"'
let logs = "https://raw.githubusercontent.com/elastic/examples/refs/heads/master/Common%20Data%20Formats/apache_logs/apache_logs"
def "example download_logs" [] {
http get $logs
| save http-logs.txt
}
def "example parse_logs" [] {
open http-logs.txt
| lines
| parse $template
}
def "example filter_logs" [] {
example parse_logs
| where method == POST
| select url status useragent
}
def "example filter_pngs" [] {
example parse_logs
| where method == GET
| where url =~ ".png"
| where size != "-"
| into int size
| where size > 500_000
| select url status served size
}
def "example live_convert" [] {
watch input.csv { open input.csv | to json | save output.yaml }
}
alias helpme = example --help