A Nu-er Shell

03 October 2024

Updated: 04 October 2024

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
Terminal window
1
> ls
2
3
╭───┬─────────────┬──────┬───────────┬────────────────╮
4
# │ name │ type │ size │ modified │
5
├───┼─────────────┼──────┼───────────┼────────────────┤
6
0 config.nu file 1.000 B a month ago
7
1 env.nu file 4.3 KiB a month ago
8
2 history.txt file 193.6 KiB 12 minutes ago
9
3 scripts dir 256 B 2 months ago
10
╰───┴─────────────┴──────┴───────────┴────────────────╯

Pipelines

  • A functional programming technique
  • Feels a bit like LINQ
  • Can be chained together and composed
Terminal window
1
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
Terminal window
1
open data.csv | to json | save data.json

The Nu Language

Terminal window
1
# compose with command utilities
2
let contents = cat my-file.txt
3
4
print $contents
5
6
# define custom functions/commands
7
def "my custom command" [name:string] {
8
"Hello " + $name
9
}
10
11
# use a module
12
use my_module.nu
13
14
# load a source file into scope
15
source my_file.nu
16
17
# create an alias
18
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

Terminal window
1
const url = 'https://dummyjson.com/todos'
2
3
# This is the main method, running --help will show docs for all subcommands
4
def example [] {
5
print "Working with HTTP Data"
6
}
7
8
def "example get_full" [] {
9
http get $url --full
10
}
11
12
def "example filter_todos" [] {
13
http get $url
14
| get todos
15
| where completed == false
16
| select id todo userId
17
| to yaml
18
}
19
20
21
let template = '{ip} - - [{date}] "{method} {url} {protocol}" {status} {size} "{served}" "{useragent}"'
22
23
24
let logs = "https://raw.githubusercontent.com/elastic/examples/refs/heads/master/Common%20Data%20Formats/apache_logs/apache_logs"
25
26
def "example download_logs" [] {
27
http get $logs
28
| save http-logs.txt
29
}
30
31
def "example parse_logs" [] {
32
open http-logs.txt
33
| lines
34
| parse $template
35
}
36
37
def "example filter_logs" [] {
38
example parse_logs
39
| where method == POST
40
| select url status useragent
41
}
42
43
def "example filter_pngs" [] {
44
example parse_logs
45
| where method == GET
46
| where url =~ ".png"
47
| where size != "-"
48
| into int size
49
| where size > 500_000
50
| select url status served size
51
}
52
53
def "example live_convert" [] {
54
watch input.csv { open input.csv | to json | save output.yaml }
55
}
56
57
alias helpme = example --help