Recycling my comment from last time this came up. Some reasons I prefer Nushell over PowerShell:
- less verbose syntax
- better cross-platform support (PowerShell is technically cross-platform, but it has some baggage from its Windows-first history)
- way faster to start up
I'm biased (I'm a member of the Nushell core team), but those are all things that drew me to start contributing to Nushell.
On the other hand, Nushell is certainly less mature+stable than PowerShell. And if Windows administration is your main use case, PowerShell can't really be beat.
The fact PowerShell has this masochistic tendency to have commands that start with capital case already makes it outside of the realm of consideration for me. It's absolute nonsense. Also I have to say your example is extremely confusing and would probably take quite a bit of time to write IRL. For reference, the equivalent in sh would be:
find . -maxdepth 1 -type f -size +10M -exec ls -lt {} +
Or a very terse example:
du -s -h * | sort -r -h | sed 10q
The thing is that if you're already used to POSIX-compliant shells then this is simply natural to write. Nushell has a different proposition of making it closer to natural language, which makes the learning curve much better. PowerShell just makes it different, but not really that much better.
Also this is somewhat tangential, but I hate that PowerShell 5 and 7 are completely different things, and that PowerShell 5 is still the default even in Windows 11.
Oh yeah, and just for lols this is the same thing in zsh:
ls -lt *(.L+10240k)
By the way, I should note that it's possible to make the PowerShell example much simpler like the following:
gci | ? Length -gt 10MB | sort LastWriteTime
The thing that really gets me here is the need to know aliases to keep it short, if you were to do it without the aliases it would look like this:
Commands aren't case sensitive. Just try it! Tab completion even works if you start the command lowercase.
As for needing to know aliases... Did the knowledge that 'du' stands for 'disk usage' exist in your brain at birth, or did you have to learn it somehow? That criticism is nonsense.
At least with powershell, commands have a canonical, explicit name with standard verbs and nouns; and a short alias that's equivalent to the initial command in every way. What I also like is that parameters have aliases too: you can write - WhatIf or -wi and it'll work the same. And everything is documented.
PowerShell command names, their parameters, string comparison, and regex matching are all not case sensitive, unless you want them to be.
It really gets you that you need to know aliases to keep it short? So why aren't you writing:
du --summarize --human-readable | sort --human-numeric-sort --reverse | sed --expression='10q'
`-exec ls -lt {} +` is not good because -exec is not handled by the shell so it behaves differently to running other commands, because `+` is a nonstandard command terminator, because {} is a nonstandard placeholder and because using `find` to run commands is an onion nobody would guess.
In your terse example, `sort -h` depends on you having run `du -h` to trigger the matching "serialise information to text" and "parse information out of text" that they both need to make that one use work, because there's no separation of content and presentation (like PowerShell has) and no structured data to pass between different commands.
Not only will PowerShell tab-complete the names and the parameters, it will tab complete the properties Length and LastWriteTime because it can tell what objects come out of Get-ChildItem and what their available properties are.
> "Also, again, case-sensitive commands make me mad."
You do understand that du, find, sort, sed are case sensitive commands with case sensitive parameters, right?
I think I'm an outlier/odd-one for liking PowerShell, but terseness hasn't been a goal for me when I write in PS. I typically write and maintain long scripts and spelling everything out helps me keep track of the logic.
It's not the best language for anything, but working a Windows shop, I'd rather bang stuff out in PS than grind my way through Visual Studio/C# for simple tasks.
Only on Windows. On Linux it's the original `ls`. Same for `cat` and many other commands. That's why using `gci` / `gc` is safer if you want your script to work everywhere.
Aliases can be redefined in certain situations (such as compiling a LCM configuration into a MOF for use with PowerShell DSC). The only safe way to script is to use the full command names (Verb-Noun).
Command names can be shadowed, you can `function get-content { "hello world" }` and that also breaks gc alias. The only safe way to script is to use the full command names including module names `Microsoft.PowerShell.Management\Get-Content`
I don't mind the looks but I find it hard to debug and have a poor instinct for "does this need a curly bracket or a parens?" That's my real issue with PowerShell, I find it very hard to predict what will work unless I know exactly what the rule is.
Shell has similar issues but I've put 20 years into it so the knowledge is there. Every time the PowerShell people describe PowerShell I think "that sounds awesome" but the ergonomics don't work for me.
Parentheses are for grouping. Curly brackets are for creating a new script block. If you would have wanted to write "function foo() {}" in another language, go for curly brackets. It's really not that complex.
Blocks always use braces. Expressions use parentheses for grouping sub-expressions. It's the same as many C-like languages. I can't imagine any situation where you would be confused which one you need to use.
Because it's an arbitrary piece of code that needs to be re-evaluated for every input item, like an inline function / lambda in other languages, not an expression that is evaluated once when the commandline is instantiated.
Blocks always use braces, but sometimes you are passing parameters and other times you are passing a block.
If I spent all day as a PowerShell dev I'm sure I would know it, but for something I reach for once or twice a year intuitiveness is a feature I would like to have.
I'd say that $_ is really weird and looks horrible. Also having to do (10 * 1024 * 1024) instead of just writing 10MB is a downgrade even compared to POSIX-compliant sh. In my other comment I've added a few examples in sh, zsh, and a better PowerShell example:
NuShell is properly MIT-licensed, and is therefore Free Software.
Powershell is kind of MIT-licensed, except for the parts that aren't but are still an integral part of it, so not really, and is therefore not Free Software. At least, it's not DFSG-free.
To be honest, they have good reason. Being written in a strongly typed, memory-safe language is a huge advantage. Obviously it's not the primary thing to look out for, but I do prefer tools that are written in it.
But why? There is nothing about a shell that requires zero cost abstractions or no gc. It farms all of its work out to other executables. A shell could be written in literally any language.
I'm not really sure which other popular languages would be considered memory safe AND strongly typed. I know of both C and C++ which I wouldn't consider memory safe. And I know of Javascript, which is not strongly typed... so which do you mean?
This is moving the goal post a bit, since the person I replied to was considering JavaScript, but I don’t really think this distinction matters. You get most programs from a package manager.
I am curious though why you don’t count graal or .net aot? They are valid options to produce an aot binary and C# has been able to produce a self contained non-aot runtime for a long a time.