Nushell 0.60 Released
nushell.sh
nushell.sh
Nu isn't quite 1.0 yet but this is the first release I can see using as my daily driver. There are a few rough edges and things aren't 100% stable yet, but I'm really impressed by the overall level of polish. Using Nu is like a glimpse into a future where string parsing is largely a thing of the past.
I've been helping out a bit with the documentation; if you have questions about getting started with Nu or if anything in the docs is unclear, let me know! https://www.nushell.sh/book/
Bringing datastructures to the shell environment (instead of everything being strings) is just the right thing to do, and I've been personally interested in making binaries that can natively input/output these data structures.
big thanks to the team, this stuff is cool.
It's easy to pipe text-speaking tools into Nu pipelines, and there's a built-in `lines` command that will split line-break-delimited text into a list of strings. From there you can use lots of tools to operate on each line.
Going from Nu data structures to raw lines of text is a little clumsier (`str collect (char newline)` IIRC) but I think that will get improved soon enough.
There's also a handy `detect columns` command that does a pretty good job of automatically converting text tables from old *nix/Windows tools into Nu tables.
Is that what Nushell is in a nutshell?
I think it really clicked for me when i read somewhere in an example `ls | sort-by size` and `ls | where size > 100mb`. They are both simple operations that i cannot accomplish from memory using standard POSIX tools, yet one year later i can remember the nushell example very well.
- no support for background tasks, or resummoning stopped processes
- while completion was added in 0.60, it doesn't look quite as featureful as zsh completion, and of course it doesn't have as many completions written as older shells
- less common need, but I don't think there is a way to do something like `exec {myvar}>file`
- I don't think there is an equivalent of `<(command)` to pass the output of a command to another command as a file. Although that could probably be implemented as a plugin pretty easily.
I might be misunderstanding this, but piping to `save` is how you usually redirect to a file in Nu: https://www.nushell.sh/book/commands/save.html
From the bash man page:
> Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form {varname}. In this case, for each redirection operator except >&- and <&-, the shell will allocate a file descriptor greater than or equal to 10 and assign it to varname. If &- or <&- is preceded by {varname}, the value of varname defines the file descriptor to close. If {varname} is supplied, the redirection persists beyond the scope of the command, allowing the shell programmer to manage the file descriptor himself.
> /Users/tom> ps | grep "k9"
Unsupported: Row(Dictionary { entries: {"pid": Value { value: Primitive(Int(359)), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }, "name": Value { value: Primitive(String("backupd-helper")), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }, "status": Value { value: Primitive(String("Unknown(0)")), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }, "cpu": Value { value: Primitive(Decimal(BigDecimal("0.000000000000000"))), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }, "mem": Value { value: Primitive(Filesize(0)), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }, "virtual": Value { value: Primitive(Filesize(0)), tag: Tag { anchor: None, span: Span { start: 3, end: 5 } } }} })
error: Received unexpected type from pipeline (row)
┌─ shell:2:6
│
2 │ ps | grep "k9"
│ ^^^^ expected a string, got row as input
I understand what happened here, but sometimes I really want to just grep through stuff. It's not clear how to do this and there isn't much in the docs about it. Without this I'm not sure I could actually switch.ps | find k9
That will search through every column in the `ps` results. If you want to look through just the name column:
ps | where name =~ k9
This was always my big annoyance with Powershell too, the shell builtins and functions were powerful, but interacting with "dumb" old-style programs that expect and emit streams of text was cumbersome.
Also, is `ps` here a wrapper or shell builtin? Or is Nushell actually parsing the output from the `ps` program?
Going from Nu to raw text is currently a little awkward. `str collect (char nl)` will take a Nu list of strings and convert it to raw text with line breaks. I suspect we'll get a more ergnomic way to do this soon.
Going to Nu from raw text is nicer, the built-in `lines` command splits line-break-delimited text into a list of strings. From there you can use lots of Nu tools to operate on each line.
On the other hand, in 10+ years using it I had to use C# inside no more then couple of times. Accessing other stuff via native calls (such as [DateTime]::Now or [string]::IsEmptyOrWhiteSpace) is more common.
Having said that, Powershell suffers from the same problem as .NET: slow startup. It's improved massively in the last few versions and I think it will get even faster once it's built using NativeAOT in .NET 7. But it can also never be as fast as .NET, since it's interpreted. So there's that.
This is a popular belief but I don't think it's true that .NET has slow startup. The CLR starts up in milliseconds, the JIT's first-tier compilation is crazy fast, and if you need to it's trivial to ship precompiled code using ReadyToRun. I don't know what makes PowerShell so slow to start up but I wouldn't blame it on .NET without more evidence.
1. Windows defender (it slows down any file access by the factor of 10 at least)
2. Virtual machine / VDI (I had 5-10s startup time on my VDI)
3. Slow modules to load (particularly those that source ps1 files instead having everything in psm1, but this is easy to diagnose as you can start it without modules)
Other then that, I never had startup time longer then 1s with bunch of modules. While that is not ultra fast, its not slow either. I must have been using it on thousand+ different machines and OSes.
Furthermore, its incomparable to bash, since once started, you rarely have to load any external processes. As an example to get something from REST API and sort and convert to CSV you can use only pwsh cmdlets, while in bash you need to use curl, jq, sort, awk etc. just for this one command. So such scripts must be slower, particularly on Windows where processes are more expensive.
Basically, instead of sourcing the nix.sh script in your shell config file (.bashrc or equivalent), you manually add the two significant nix directories to your path in the Nu config file.
The Nix Manual[1] explains what the nix.sh script does: "To use Nix, some environment variables should be set. In particular, PATH should contain the directories prefix/bin and ~/.nix-profile/bin." So it's as easy as adding those to your path in the config file, which in Nu looks like `let-env PATH = [...other path elements, "path/to/home/dir/.nix-profile/bin", "/nix/var/nix/profiles/default/bin"]`.
[1] https://nixos.org/manual/nix/stable/installation/env-variabl...
"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."
So often there's link to some new release of something and I have no idea what it does. I'm not sure why more projects don't start with an explanation of what that project is/does!