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