Nushell 0.40

Nushell, or Nu for short, is a new shell that takes a modern, structured approach to your commandline. It works seamlessly with the data from your filesystem, operating system, and a growing number of file formats to make it easy to build powerful commandline pipelines.

Today, we're releasing 0.40 of Nu. This release is includes better table imports and much smaller release size.

Where to get it

Nu 0.40 is available as pre-built binariesopen in new window or from crates.ioopen in new window. If you have Rust installed you can install it using cargo install nu.

If you want all the goodies, you can install cargo install nu --features=extra.

As part of this release, we also publish a set of plugins you can install and use with Nu. To install, use cargo install nu_plugin_<plugin name>.

What's New

Detecting columns (sophiajt)

Nushell now supports a new command: detect columns. This command is intended as an easy way to handle tabular data that's written as text. Commands like ps, ls -l, netstat, df, and others commonly output their output as text. With detect columns, you can run the external command, and convert them into Nushell's tabular data format.

Let's look at an example:

> df
Filesystem     1K-blocks      Used Available Use% Mounted on
udev             8108824         0   8108824   0% /dev
tmpfs            1631284      2068   1629216   1% /run
/dev/nvme1n1p2 490691512 346066860 119629172  75% /
tmpfs            8156408    251332   7905076   4% /dev/shm
tmpfs               5120         4      5116   1% /run/lock
tmpfs            8156408         0   8156408   0% /sys/fs/cgroup
/dev/nvme0n1p1    508932    211684    297248  42% /boot/efi
tmpfs            1631280       128   1631152   1% /run/user/1000
/dev/nvme0n1p2 238810780 136867812  89742316  61% /media/sophiajt/Data

The df command comes with most Unix-based systems and prints out a table of data for each of the devices on the system. Let's turn this into a table we can work with in Nushell:

> df | detect columns
───┬────────────────┬───────────┬───────────┬───────────┬──────┬────────────────┬────────────────
 # │   Filesystem   │ 1K-blocks │   Used    │ Available │ Use% │    Mounted     │       on
───┼────────────────┼───────────┼───────────┼───────────┼──────┼────────────────┼────────────────
 0 │ udev           │ 8108824   │ 0         │ 8108824   │ 0%   │ /dev           │
 1 │ tmpfs          │ 1631284   │ 2068      │ 1629216   │ 1%   │ /run           │
 2 │ /dev/nvme1n1p2 │ 490691512 │ 346067044 │ 119628988 │ 75%  │ /              │
 3 │ tmpfs          │ 8156408   │ 251332    │ 7905076   │ 4%   │ /dev/shm       │
 4 │ tmpfs          │ 5120      │ 4         │ 5116      │ 1%   │ /run/lock      │ /run/lock
 5 │ tmpfs          │ 8156408   │ 0         │ 8156408   │ 0%   │ /sys/fs/cgroup │ /sys/fs/cgroup
 6 │ /dev/nvme0n1p1 │ 508932    │ 211684    │ 297248    │ 42%  │ /boot/efi      │ /boot/efi
 7 │ tmpfs          │ 1631280   │ 128       │ 1631152   │ 1%   │ /run/user/1000 │ /run/user/1000
 8 │ /dev/nvme0n1p2 │ 238810780 │ 136867812 │ 89742316  │ 61%  │ /media/st/Data │ /media/st/Data
───┴────────────────┴───────────┴───────────┴───────────┴──────┴────────────────┴────────────────

Ahh, that's close to what we want in just one step. Let's go ahead and clean this up a little. First, let's drop that last column. "Mounted on" being two words confused the importer, but all the data is there, we just need to drop the last column.

> df | detect columns | drop column
───┬────────────────┬───────────┬───────────┬───────────┬──────┬────────────────
 # │   Filesystem   │ 1K-blocks │   Used    │ Available │ Use% │    Mounted
───┼────────────────┼───────────┼───────────┼───────────┼──────┼────────────────
 0 │ udev           │ 8108824   │ 0         │ 8108824   │ 0%   │ /dev
 1 │ tmpfs          │ 1631284   │ 2068      │ 1629216   │ 1%   │ /run
 2 │ /dev/nvme1n1p2 │ 490691512 │ 346067188 │ 119628844 │ 75%  │ /
 3 │ tmpfs          │ 8156408   │ 251332    │ 7905076   │ 4%   │ /dev/shm
 4 │ tmpfs          │ 5120      │ 4         │ 5116      │ 1%   │ /run/lock
 5 │ tmpfs          │ 8156408   │ 0         │ 8156408   │ 0%   │ /sys/fs/cgroup
 6 │ /dev/nvme0n1p1 │ 508932    │ 211684    │ 297248    │ 42%  │ /boot/efi
 7 │ tmpfs          │ 1631280   │ 128       │ 1631152   │ 1%   │ /run/user/1000
 8 │ /dev/nvme0n1p2 │ 238810780 │ 136867812 │ 89742316  │ 61%  │ /media/st/Data
───┴────────────────┴───────────┴───────────┴───────────┴──────┴────────────────

Finally, it'd be nice to be able to have real file sizes for the middle columns, so let's convert the numbers into Nushell's filesize type:

> df | detect columns | drop column | into filesize 1K-blocks Used Available
───┬────────────────┬───────────┬──────────┬───────────┬──────┬────────────────
 # │   Filesystem   │ 1K-blocks │   Used   │ Available │ Use% │    Mounted
───┼────────────────┼───────────┼──────────┼───────────┼──────┼────────────────
 0 │ udev           │    8.1 MB │      0 B │    8.1 MB │ 0%   │ /dev
 1 │ tmpfs          │    1.6 MB │   2.1 KB │    1.6 MB │ 1%   │ /run
 2 │ /dev/nvme1n1p2 │  490.7 MB │ 346.1 MB │  119.6 MB │ 75%  │ /
 3 │ tmpfs          │    8.2 MB │ 251.3 KB │    7.9 MB │ 4%   │ /dev/shm
 4 │ tmpfs          │    5.1 KB │      4 B │    5.1 KB │ 1%   │ /run/lock
 5 │ tmpfs          │    8.2 MB │      0 B │    8.2 MB │ 0%   │ /sys/fs/cgroup
 6 │ /dev/nvme0n1p1 │  508.9 KB │ 211.7 KB │  297.2 KB │ 42%  │ /boot/efi
 7 │ tmpfs          │    1.6 MB │    128 B │    1.6 MB │ 1%   │ /run/user/1000
 8 │ /dev/nvme0n1p2 │  238.8 MB │ 136.9 MB │   89.7 MB │ 61%  │ /media/st/Data
───┴────────────────┴───────────┴──────────┴───────────┴──────┴────────────────

In just a couple steps, we've converted the text-based table into tabular data we can use just like any other Nushell command. To make this easy to do in the future, we can alias df to do these steps:

> alias df = (^df | detect columns | drop column | into filesize 1K-blocks Used Available)

Smaller binaries (fdncred)

The size of the Nushell release binaries has come up as regular feedback from Nushell users. "Why does the shell have to be so big?" And we've heard you!

Today's release now uses a combination of strip and upx to bring considerable savings in binary size. The Linux release (plugins incl.) has dropped from 475mb to 58mb(!!), making it 88% smaller. We're seeing similar improvements in the sizes of the macOS and Windows releases.

Additional fixes

Engine-q progress

We've also hit a milestone with engine-q: now over 100 commands have been ported to engine-q! Special thanks to onthebridgetonowhere, CBenoit, luccasmmg, stormasm, and aslynatilla for their work in these ports since the last Nushell release.

We've also added support for $configopen in new window, $inopen in new window, a new record syntaxopen in new window, ls colorsopen in new window, environment variable module importsopen in new window, and much more. While engine-q isn't quite ready to be tested as a daily driver, with each day its capabilities and stability grows.

If you're interested in how some of the upcoming support for parallel processing in engine-q works, contributor Sophia made a video explaining itopen in new window.

Looking forward

We're excited to see Nushell continue to gain more ability to work with data in easier ways as well as doing so in as a much smaller binary. Progress on engine-q continues to grow, and covers a large amount of ground in the engine internals, porting commands, plugin support, modules, and more.

If you're interested in helping out, come join us on the discordopen in new window. We're more than happy to help answer questions and point you towards on-going projects!