Skip to content

Commit cc23639

Browse files
committed
new-blog: Nushell, after 8 months
1 parent ac1d84c commit cc23639

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

_components/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ footer {
246246
display: flex;
247247
justify-content: space-between;
248248
color: var(--dim-text-color);
249-
font-size: 1.2em;
249+
font-size: 1.0em;
250250
}
251251

252252
footer a {
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
cover: false
3+
title: 'Nushell, after 8 months'
4+
description: "I have been using nushell as my primary shell for the last 8 months and I don't see myself going back to bash or zsh or powershell"
5+
date: 2024-04-29 11:15:00
6+
tags: ['shell', 'nushell', 'cli', 'unix', 'powershell']
7+
---
8+
9+
> ... Plain text is definitely simpler than tables. So maybe we are just moving complexity here. Or this is a very good abstraction and a lot of things improve. Time will tell.
10+
11+
[Me, 8 months ago](https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/)
12+
13+
And the last 8 months have told me - Tables are a very good abstraction for CLI. No doubt. Possibly because they retain the fundamental nature of [Values](https://youtu.be/-6BsiVyC1kM?si=w1U3f4OzdOAT6C55). In fact, tables are already present in unix shell, hiding in plain text. `ps`, `ll`, `kubectl` and many more programs have a tabular output. And to do anything with them, it's a lot more easier in `nushell` than in `bash` or similar shells.
14+
15+
## Surprisingly seamless 🧈
16+
I had my concerns initially - "Won't I face a lot of issues with all the unix programs, that just expect plain text and output plain text?". But it's barely been a problem. `nushell`'s inbuilt commands and operators just take care of converting plain text to structured data and extract the necessary values to pipe them back into other programs.
17+
18+
Let's take an example. Get the first pod's name with the status `Running` in a kubernetes cluster and enter it's shell?
19+
20+
```sh
21+
$ kubectl -n namespace get pods
22+
```
23+
gets you a table like this
24+
25+
```
26+
NAME READY STATUS RESTARTS AGE
27+
namespace-86c7df9555-4n9cc 1/1 Running 0 2d2h
28+
namespace-86c7df9555-65nks 1/1 Running 0 2d2h
29+
namespace-86c7df9555-cdzll 1/1 Running 1 (35h ago) 2d1h
30+
namespace-86c7df9555-dlpnx 1/1 Running 0 35h
31+
namespace-86c7df9555-fnrgd 1/1 Running 0 2d2h
32+
namespace-86c7df9555-lnx2v 1/1 Running 0 2d1h
33+
namespace-86c7df9555-nmwrx 1/1 Running 0 2d2h
34+
namespace-86c7df9555-xv45m 1/1 Running 0 35h
35+
```
36+
This is just plain text but pipe it into `detect columns` and we get an actual `nushell` table
37+
38+
```sh
39+
$ kubectl -n namespace get pods | detect columns
40+
```
41+
42+
<img src="https://imgur.com/9lVQPJ0.png" style="max-width: 600px;" />
43+
44+
Now we can filter the rows with `where` and get the first row with `first`
45+
46+
```sh
47+
$ kubectl -n namespace get pods | detect columns | where { $it.STATUS == "Running" } | first | get NAME
48+
```
49+
50+
We can store this in a variable and access the shell with `kubectl exec`
51+
52+
```sh
53+
$ let pod_id = kubectl -n namespace get pods | detect columns | where { $it.STATUS == "Running" } | first | get NAME
54+
$ kubectl -n namespace exec -it $pod_id -- /bin/bash
55+
```
56+
57+
Or just put it in `()` brackets and use it directly
58+
59+
```sh
60+
$ kubectl -n namespace exec -it (kubectl -n namespace get pods | detect columns | where { $it.STATUS == "Running" } | first | get NAME) -- /bin/bash
61+
```
62+
63+
Working within `nushell` has been a lot like working with the programming languages that I am used to. It feels like I am in a REPL of one of those languages. Familiar and comfortable.
64+
65+
## Perfect for data wrangling ⚙️
66+
Lately I have been working with some csv files and what a delight it has been to work with them in `nushell`.
67+
68+
Colleague pings me saying "Here are the leads we want to add to the database - leads.csv".
69+
70+
I take a look at the file and there are some invalid user_ids in the file.
71+
72+
```sh
73+
open leads.csv | where { ($it.user_id | describe) != 'int' } | count
74+
```
75+
I inform him - "Hey, we have 32 invalid user_ids in the leads.csv file. I will ignore them for now." and move on.
76+
77+
```sh
78+
open leads.csv | where { ($it.user_id | describe) == 'int' } | get user_id | str join ',' | pbcopy
79+
```
80+
(Copies the user_ids to the clipboard)
81+
82+
I can probably do the same with `awk` and `sed` in `bash`. But this is a lot more simpler for me. Possibly because I work with object oriented languages a lot. And commands like `where`, `first`, `take`, `skip` are very familiar to me because all the languages have adopted these functional paradigms for operating with collections / streams.
83+
84+
By the way, if I want to convert that CSV to JSON?
85+
86+
```sh
87+
open leads.csv | to json | pbcopy
88+
```
89+
Ready to just paste it into a node REPL.
90+
91+
This works with CSV, JSON, YAML, TOML, SQLite and [many more formats](http://www.nushell.sh/book/loading_data.html#opening-files). This came in handy to check which exact version of package is being used in a `package-lock.json` file a number of times.
92+
93+
```sh
94+
open package-lock.json | get dependencies | get ws | get version
95+
```
96+
97+
## It can't all be that good, can it?
98+
While I was about to adopt a new shell that's not 1.0 yet, I was expecting to deal with some rough edges.
99+
100+
> It feels like a pre-honeymoon phase with nu. So there is a lot of adulation right now. It's likely that there are a lot of sour learnings to follow
101+
102+
[Me, 8 months ago](https://okmanideep.me/i-am-very-excited-about-using-nushell-everyday/)
103+
104+
To be honest, I didn't have to deal with many issues. But there was one which took a bit of time to figure out.
105+
106+
[fnm](https://github.com/Schniz/fnm) - fast node version manager, only offer setup instructions for `bash`, `zsh`, `fish` and `powershell` to add necessary changes to the shell profile for the right $PATH. For `nushell`, we have to use something like this
107+
108+
```sh
109+
# fnm - node version manager
110+
# https://dev.to/vaibhavdn/using-fnm-with-nushell-3kh1
111+
load-env (/opt/homebrew/bin/fnm env --shell bash | lines | str replace 'export ' '' | str replace -a '"' '' | split column = | rename name value | where name != "FNM_ARCH" and name != "PATH" | reduce -f {} {|it, acc| $acc | upsert $it.name $it.value })
112+
113+
$env.PATH = ($env.PATH | prepend $"($env.FNM_MULTISHELL_PATH)/bin")
114+
```
115+
116+
Essentially fake the shell, get the necessary changes and apply them to the `nushell` environment.
117+
118+
Some extra work to setup programs that output configuration for bash / zsh etc. And a few copy pasta for setting up some completions.
119+
120+
That's about it. After I have setup `nushell` in my system and added it to my [dotfiles](https://github.com/okmanideep/dotfiles), it's been a smooth ride across both Windows and MacOS. I have been using `nushell` as my primary shell for the last 8 months and I don't see myself going back to `bash` or `zsh` or `powershell`.

0 commit comments

Comments
 (0)