[Short Tip] Doing for-loops in Nushell

Nushell 0.32 added support for typical for loops:

With the new for..in command, you can write more natural iterating loops:

Nushell 0.32 release notes
> for $x in 1..3 { echo ($x + 10) }
───┬────
 0 │ 11 
 1 │ 12 
 2 │ 13 
───┴────

Compared to what we have in Bash and others (and given my limited understanding) the most notable difference is that there is no “do”, but instead a curly bracket defining what should be done.

Also, remember that Nushell has an understanding of various data types, so the iterator in the example above is indeed of type “int”. Just stitching it together with another string doesn’t work:

❯ for $i in 1..3 {echo ("/home/" + $i) }
error: Coercion error
   ┌─ shell:31:23
   │
31 │ for $i in 1..3 {echo ("/home/" + $i) }
   │                       ^^^^^^^^   -- integer
   │                       │           
   │                       string

Instead, make sure to echo the iterator:

❯ for $i in 1..3 {echo $"/home/(echo $i)" }
───┬─────────
 0 │ /home/1 
 1 │ /home/2 
 2 │ /home/3 
───┴─────────

For comparison, if you have a set of strings you can provide them in a table and stitch them together easily:

❯ for $i in [a b c d] {echo ("/home/" + $i) }
───┬─────────
 0 │ /home/a 
 1 │ /home/b 
 2 │ /home/c 
 3 │ /home/d 
───┴─────────

[Short Tip] Access system variables in Nushell

Working with variables in Nushell works mostly like you would expect it. If you want to define a variable, you need the keyword let:

❯ let my_variable = "hello blog readers"

❯ echo $my_variable
hello blog readers

Note that you need the spaces around the equal sign character!

❯ let my_variable="hello blog readers"
error: let requires the equals sign parameter
   ┌─ shell:21:1
   │
21 │ let my_variable="hello blog readers"
   │ ^^^ requires the equals sign parameter

But apart from defining your own variables, there is a surprised when you try to access typical system variables:

❯ echo $HOME
error: Variable not in scope
   ┌─ shell:25:6
   │
25 │ echo $HOME
   │      ^^^^^ unknown variable: $HOME

The reason for that error is that Nushell places system environment variables underneath the main variable $nu:

❯ echo $nu|pivot
───┬─────────────────┬────────────────────────────────────────────
 # │     Column0     │                  Column1                   
───┼─────────────────┼────────────────────────────────────────────
 0 │ env             │ [row 34 columns]                           
 1 │ history-path    │ /home/liquidat/.local/share/nu/history.txt 
 2 │ config          │ [row path prompt startup]                  
 3 │ config-path     │ /home/liquidat/.config/nu/config.toml      
 4 │ path            │ [table 5 rows]                             
 5 │ cwd             │ /home/liquidat
 6 │ home-dir        │ /home/liquidat
 7 │ temp-dir        │ /tmp                                       
 8 │ keybinding-path │ /home/liquidat/.config/nu/keybindings.yml  
───┴─────────────────┴────────────────────────────────────────────

❯ echo $nu.env|pivot
────┬──────────────────────────┬────────────────────────────────────────────────────
 #  │         Column0          │                      Column1                       
────┼──────────────────────────┼────────────────────────────────────────────────────
  0 │ CMD_DURATION_MS          │ 2                                                  
  1 │ HOME                     │ /home/liquidat                                            
  2 │ SYSTEMD_EXEC_PID         │ 2958                                               
  3 │ SSH_AUTH_SOCK            │ /run/user/1000/keyring/ssh                         
  4 │ SESSION_MANAGER          │ local/unix:@/tmp/.ICE-unix/2557,unix/unix:/tmp/.IC 
    │                          │ E-unix/2557                                        
  5 │ GNOME_TERMINAL_SCREEN    │ /org/gnome/Terminal/screen/71e37281_4af2_4c9b_be19 
[...]

❯ echo $nu.env.HOME
/home/liquidat

The environment variables are generated from the environment Nushell was started in. If you need to update those for the current environment, use the command let-env:

❯ echo $nu.env.LANG
en_US.UTF-8

❯ let-env LANG = C

❯ echo $nu.env.LANG
C

Image by Susanne Westphal from Pixabay

[Short Tip] Add a path entry to Nushell

Adding a path in nushell is pretty straight forward: the configuration is done in ~/config/nu/config.toml in the [path] section.

If you don’t have it, make sure that the default entries are listed there as well when you start bringing in your own directories. The fastest way to populate your configuration with the default entries is to ask nushell to do it: config set path $nu.path

Next, add the directories you need:

path = ["/usr/local/bin", "/usr/local/sbin", "/usr/bin", "/usr/sbin","/home/rwolters/go/bin"]

In the above example I added the default go binary directory to the list.

[Short Tip] Define an alias in Nushell

A few days ago I decided to switch my main shell to nushell. It offers next generation capabilities similar to other modern shells like Powershell:

Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure. For example, when you list the contents of a directory, what you get back is a table of rows, where each row represents an item in that directory.

Nushell Philosophy

This switch feels like the biggest shell related change for me since I switched from Windows Command Prompt to Bash. Even the switch from Bash to ZSH was small in comparison.

As part of this I have to relearn how to do a lot of things. For example, defining an alias is totally different.

The nushell configuration takes place in ~.config/nu/config.toml. To add an alias there, add the section startup if it is not there already, and add a list item there:

startup = [
    "alias evince = flatpak run org.gnome.Evince",
    "alias ll = ls -la",
    ]

In the above example two aliases are given, one to call ls, and one for launching evince via flatpaks.

Image by julia roman from Pixabay