GitHub – nushell/nushell: A new type of shell
github.com
github.com
Would really love to read from people who use(d) an alternative shell, both success and failure stories.
I cannot shake from my head the idea that buying into a non-standard shell will only work for personal projects in one's own workstation, but it won't fly too far for company work because you'd then be introducing an implicit dependency on your special snowflake non-standard runtime. Which is something we came to accept and assume for interpreted languages (Python, Ruby, Node, etc.) but I'm not yet ready to assume for shell scripts.
So right when I was going to test Nushell, I discover there are also other shells like Elvish [0] and Oil which supports structured data [1]. Now on top of my hesitations I'm adding decision paralysis :-]
[0]: https://elv.sh/
[1]: https://www.oilshell.org/
Lots more shells: https://github.com/oilshell/oil/wiki/Alternative-Shells
For me, personally, I love having homogeneus systems put in place. In this case it means not having to switch my mind between in and for modes. Helps me avoid mistakes, having to keep less context up here. But it's always interesting to read about other people's way of working.
I find that it is better to allow each team member to have their own working environment: different (command line) shell, different editors/IDEs, different keyboard shortcuts. But everyone uses the same programming languages (counting shell as a programming language for scripts here) and the same build tools and the same linters.
But of course, I believe others should be free to make their own choices! As long as their choices don't end up affecting the quality of the code that ends up shared with the rest of the team...
Which brings an interesting point: I don't have a problem at all with you using whatever shell you want. But I do have a problem if because you don't use Bash in your day to day, you are less used to its ins and outs, you don't put in the extra work that is being as proficient with Bash than you are with your personal shell, and your scripts end up with bugs in how Bash arrays are treated (just a quickly made up example)
It seems like a lot of the developers of these shells create them to supplement the common unix toolset, but I really want a complete replacement. Ideally, the shell itself would be a completely dependency-free static executable, with a built-in command set that includes functions to interface with all the kernel's user space accessible features, acts as a repl, with sensibly named commands, and a simple method for interfacing to and from any other program. In short, I guess I'm looking for something to act as the basis of a completely new environment on top of Linux. As it is, most of these do not even meet the first of the criteria.
In my experience, the middleman you mention doesn't exist. Or, if anything, it is a very tiny man that hardly gets in the way. It's either a one-liner with a syntax change you can pick up in 5 minutes, or it falls under any combination of these:
- might as well belong in a script
- the complicated stuff is in awk or the likes
- you can just enter bash for any copy-pasted bashisms
- you can execute it explicitly with bash -c
In any case, none enough of a hassle that it could demerit the immense productivity benefit I've gotten from fish. The only regret I have on that matter is not having ditched it sooner. Use bash to run scripts, or even better, sh. Use a different shell to make your life on the terminal better. Doesn't need to be fish, zsh is pretty good too.
If I can offer any advice: if you still want to stick with bash, at the very least take a look at fzf, https://github.com/junegunn/fzf , aside from fish/zsh it's the best and most lowest hanging fruit.
Given that 95% of my time in a shell is running a script, a shell that doesn't do that well isn't a great fit for me.
> A shebang on the top of your script will invoke the script with the right executable,
Assuming the person who wrote it had the foresight to do so. That person isn't always me, and if I have to manually check if each script I run has a shebang, I should just default to running them in bash.
I’ve started to write dash scripts because that seems to be reasonably posix and bash on macOS is ancient.
Even the most basic of tutorials will include it even if it means nothing to the user.
For the longest time bash was in various states of disrepair on different Unixes. I could make it segfault pretty easily.
I wrote scripts that had to run across Linux, BSD, HP-UX, Solaris, and AIX at the time. So we relied on a ksh88 implementation on each. Whether it was AT&T, mksh, or pdksh, it was fine. Couldn't rely on 93isms, but basically anything POSIX was cool.
I used ksh93 interactively for the longest time. But then Linuxes stopped testing interactive use w/ their packages and it became unusable (looking at you RedHat). So I used bash interactively but still wrote those ksh scripts.
These days, I use zsh locally on MacOS and BSD, but mostly write bash scripts for those and Linux. I still stick to the POSIX habits I have for portability. But the variances are so less. The only one that annoys me is the "does sed -i do in-place" game.
I don't think my interactive shell and target scripting shell have ever matched 1:1 in feature set. And what I slap together interactively or for 1-off script, I would never do for a "real" script. And that's a thing that bugs me with a lot of shell scripts I see in the wild.
A "real" script should make very little assumptions, fail safely, be low on resource utilization to not risk impacting a business workload, and be maintainable. I write everything real like it might be run thousands of times accross thousands of hosts. Even when I didn't intend for it to be, I've caught it in the wild because someone borrowed what I did.
I do love shellcheck, because it teaches our newer folks good habits and they're used to that kind of feedback in other languages. It catches so many things that make me cringe. It's not perfect, of course, but pretty great.
When I started out, I worked 9-6 and the Unix sages in my group worked later hours. So they'd walk through my work on the RCS host and I'd come into the morning with a critique in my email. If I didn't understand, I could hit their desk after lunch and they would patiently explain to me. I love them for it, but it is nice to have tools without a 24-hour feedback loop.
x = 0 doesn't work and x=$y is a security flaw
It also got on my nerves that scripts which did not identify themselves correctly as bash would run in [ whatever hot new shell im running ], often with bizarre results.
I just use it as interactive shell and for scripts I use `/bin/sh`. So I don't really run into a lot of problems, only sometimes with scripts that do not have a proper `#!/path/to/shell` declaration at the top.
("better defaults" is of course entirely subjective but for fish, i3 and Doom Emacs they mostly align with my preferences)
When I started with Linux in the 90's it had FVWM by default as graphical interface which was pretty different when being used to Amiga, Atari ST and Windows 3.1. (They were all pretty different from each other.)
Of course I had to run Enlightenment with some rusty graphics when I discovered it, but I think WM2/WMX[1] was the first window manager where I realized I preferred the more minimalistic ones.
After trying out more WMs I ended up at awesome[2] which I ran for years. It had the best support for both floating and tiling windows. (I do like some floating windows now and then but never liked the "normal" desktop concept which is, paraphrasing Fred Brooks, more of a flight seat concept.)
Then WMs like xmonad started appearing and I tried those out but they're pretty much "tiling only" and I did not like xmonad's tiling windows approach. It's been too long since I used it and I'm not sure it is still applicable but it forced you to use specific layouts and the current window was always maximized.
So at some point i3 appeared (like fish shell and Doom Emacs) and when trying it out it by default already did most of the things that I liked and that I had to configure in other window managers, so that was nice. It was a pretty good fit right away.
I have used some other WMs like EXWM and StumpWM over the years because I'm both an Emacs and Lisp weeny but they're like less mature i3 clones so I've been back at i3 for a while now.
[0] https://xon.sh
also, why would any dependency of your projects at work be implicit? all dependencies should be captured somehow, the very least in some documentation.
at our company, we use shell.nix files to declare all of our dependencies, so everyone has the exact same software available on their development workstations.
it's not a completely trivial thing to do, but worth investing into it, to lower the chance of surprises, which will happen when you can afford them the least...
here is an example to get started:
``` with import (builtins.fetchTarball { name = "nixos-unstable-on-2021-05-16"; url = "https://releases.nixos.org/nixos/unstable/nixos-21.05pre2893... sha256 = "1kilrk0ipvldf4rrn6aq6v2bj2jfhbz33cjb9w9ngqmbmr2f94wd"; }) { };
let project-jdk = jdk11; clojure = callPackage ./deps/clojure { jdk11 = project-jdk; };
in mkShell rec { buildInputs = [ coreutils cacert direnv nixfmt curl jwt-cli fd python3 nodejs (yarn.override { nodejs = nodejs; }) project-jdk clojure yaml2json
modd
devd
overmind
];
shellHook = ''
export LC_CTYPE="UTF-8" # so tar and rlwrap won't complain
'';
}
```it shows how u would use your custom package (for clojure in our case) and how would u pin there state of the whole package repository to a specific point in time.
in the past I've used es, the extensible shell (https://wryun.github.io/es-shell/), this way, without bothering my colleagues with teaching them about it. they just git pull, press enter in a shell within the hour repo and direnv will pull down any new dependencies.
Because distributing software is hard, especially if things change. That's one big reason why Docker images will sometimes get used for development environments (like what VSCode supports).
Nix is nice, and is a pretty good way of capturing those dependencies. But it's also difficult to customise, often lacking in documentation, and not used very widely.
If you're not using something like Nix (i.e. most people), it's natural for dependencies to be quite implicit.
I'm not really an expert in the Nix expression language. Hasn't even finished reading the Nix pills, which is a very practical documentation, yet I could manage to extract a lot of benefit from that shell.nix template I've shared. I'm using Nix for 3+ years now. Because of this experience I do encourage others not to be afraid trying Nix. It gets better with every release.
Docker is a halfway solution and because of its memory and storage requirements it often strains the average development workstations and internet connections.
As a GNU screen user already, I can imaginr having one of my default windows that load when I launch screen be nushell if I was so inclined. I can keep the rest as my default (e.g., bash or htop or whatever else I wany running there).
Is it so bad? I run arch at home, I would never do that for a production server. I use rust at home, but it's unlikely to get introduced at my work any time soon. I use elm for solo projects, and I've never once convinced my managers to even try it (and believe me, I tried).
Context switching is pretty normal, I wouldn't let that get in the way of trying something new and interesting. Personally I find elv.sh the sanest scripting language I've tried so far, and I wouldn't trade it back in for bash, even if I'm still forced to use it at work.
I really like Elvish's emphasis on interactivity, its somewhat maximalist approach to interactivity-oriented builtins (like fuzzy filtering, its directory browser, etc.), and the fact that it's distributed as a single static executable.
I also like the developers, who are smart and kind people and generally pretty pleasant to interact with on GitHub or their Telegram chat (bridged to various other things).
None of this is a case against trying Oil, however, so perhaps it will not help your paralysis too much. ;)
NGS' readme also has a good comparison section listing alternative shells: https://github.com/ngs-lang/ngs#have-you-heard-of-project-x-...
Tangential, but:
- "Node" isn't a language, it's a JS runtime
- There's no such thing as an "interpreted language", whether something is interpreted or not is a property of the execution environment, not of the language itself
- The commonly-used runtimes for JS at least are JIT compilers, not "interpreters", and this can be true for some Python/Ruby runtimes too
(And for the record I know very well about the internals and technicalities about the words and names that I used: Node.js is the de-facto Javascript runtime for the backend, popular to the point that people commonly refer to it as "programming in Node"; Python and Ruby are just languages but their majority of users run their program with the default official interpreter, so through a metonymy we can refer to either even when actually talking of the other; and etc. For economy of the language and avoiding the pedantry, I grounded my comment on the most generally perceived notion about those technologies. You see, just to avoid unnecessarily long explanations like this one)
A few years back I did a startup with a friend -- a cross platform mobile product but with a mess of complex open-source c++ dependencies (which we forked and customized often) -- and we made the decision as we hired developers to over-specify some aspects of the machine environment to make it as easy as possible to share our development workflows. Note that "development workflow" is much more than just "i can run the app in docker" -- but rightfully includes -- I can efficiently run things in debugger, I can run the performance profiling tools in realistic ways, I can quickly execute and test a change someone else is trying to make, I can quickly share a change I'm making with someone else and be confident they can make realistic observations about it, i can setup a fast repro loop for some specific bug or feature ... etc.
We did a pretty good job of getting the know now needed for all those workflows distributed across the team reliably with low effort despite some complicated and weird build system requirements associated with our dependencies.
One of the big bang for buck tricks that helped more than I would've expected was to mandate that everyone had to use fish shell. This really reduces the number of weird effects from random things that people copy/paste into their bash initialization -- with the developer never imagining the strange knock off effects that will one day cause a tool they don't understand to behave in a flaky way for a reason they will never figure out ...
The amount of terrible things that developers randomly accumulate in their bash initialization probably can't be underestimated ... there's probably more risk of "weird problems" associated with advice on stack overflow related to bash initialization than maybe any other topic ...
So I personally think standardizing a team or startup on an alt shell can be a potentially good idea ...
As another point of evidence -- I later headed devops at another startup that took opposite perspective -- "use your own machine and your machine can be configured however you want and you just have to figure out dev workflows on your own" and it was extremely difficult to share knowledge about how to accomplish a lot of these basic workflows ... doing anything beyond the most basic ways of interacting with the codebase often involved a rather large amount of hands on dev machine troubleshooting (can you send me your .bashrc and .profile and .bash_profile? ok type these commands ... ok now you can grab my branch and try this to have a look at the thing i'm trying to change ...)
fish is reliable and stable though -- I'm not sure about using a shell that's not been around for awhile in this way ... but I'd support it I think if I already had personal experience that the shell was "reliable enough" ...
I've not seen this title format on HN before. Could it be changed?
1. The submitter may provide an initial title
2. HN moderators may adjust the title
3. GitHub may show different titles based on the user's login status (I'm not sure myself, I'm writing this based on what I read in another part of this thread)
Therefore, I make this request of HN commenters: Since titles on HN can change, please quote the exact title that confuses you.
More broadly, it may be useful to always quote the text you are responding to.
Universities have formed a company that looks a lot like a patent troll
was Universities Have Formed a Company That Looks a Lot Like a Patent Troll
Linux with “memory folios”: a 7% performance boost when compiling the kernel
was Linux with “memory folios”: got a 7% performance boost when compiling the kernel
Strategic Scala Style: Principle of Least Power (2016)
was Strategic Scala Style: Principle of Least Power (2014)
The rise of E Ink Tablets and Note Takers: reMarkable 2 vs Onyx Boox Note Air
was The Quiet Rise of E Ink Tablets – ReMarkable 2 vs. Onyx Boox Note Air
Big tech face EU blow in national data watchdogs ruling
was EU court backs national data watchdog powers in blow to Facebook, big tech
Emacs Love Tale by sdp
was Emacs Love Tale by Sdp
Future from a16z
was Andreessen Horowitz goes into publishing with Future
Richard Feynman’s Integral Trick (2018)
was Richard Feynman’s Integral Trick
The Tinkerings of Robert Noyce (1983)
was The Tinkerings of Robert Noyce
NIH study offers new evidence of early SARS-CoV-2 infections in U.S.
was NIH Study Offers New Evidence of Early SARS-CoV-2 Infections in U.S.
Time to sunburn
was It's surprisingly easy to get a sunburn
The home computer as a cultural object is physically vanishing (2007)
was The home computer as a cultural object is physically vanishing
Mackenzie Scott gives away another £2B
was Billionaire Mackenzie Scott gives away another £2bn
A pilot program to include spirituality in mental health care
was Psychiatry Needs to Get Right with God
What we learned doing Fast Grants
was What We Learned Doing Fast Grants
Joplin – an open source note taking and to-do application with synchronisation
was An open source note taking and to-do with synchronisation capabilities
Show HN: Influence, a Go-inspired 1-minute board game
was Show HN: Influence, a Go-inspired 1min board game
J Concepts in SuperCollider
was J Concepts in SC (SuperCollider)
Joplin – an open source note taking and to-do application with synchronization
was Joplin – an open source note taking and to-do application with synchronisation
was An open source note taking and to-do with synchronisation capabilities
Forzak: A website that curates high-quality educational content
was Forzak: A website that curates high-quality educational content on the Internet
DraftKings: a $21B SPAC betting it can hide its black market operations
was DraftKings: A $21B SPAC Betting It Can Hide Its Black Market Operations
We’re no longer naming suspects in minor crime stories
was Why we’re no longer naming suspects in minor crime stories
Operation Midnight Climax: How the CIA Dosed S.F. Citizens with LSD (2012)
was Operation Midnight Climax: How the CIA Dosed S.F. Citizens with LSD
Modelplace: AI Model Marketplace by OpenCV
was Modelplace, the AI Model Marketplace by OpenCV
Don't just shorten your URL, make it suspicious and frightening (2010)
was Don't just shorten your URL, make it suspicious and frightening
Kuhn's Structure of Scientific Revolutions – outline (2013)
was The Structure of Scientific Revolutions
How Indian Zoroastrians helped shape modern Iran
was An Indian Religious Minority Shaped Modern Iran
RFC for 700 HTTP Status Codes (2018)
was RFC for 700 HTTP Status Codes
RFC for 700 HTTP Status Codes (2012)
was RFC for 700 HTTP Status Codes (2018)
was RFC for 700 HTTP Status Codes
How to Be a Stoic (2016)
was How to Be a Stoic
Researchers fear a scenario in which smart speakers feed sleepers subliminal ads
was Are advertisers coming for your dreams?
Google Messages end-to-end encryption is now out of beta
was Google Messages end-to-end encryption no longer in beta
Stabel: A pure concatinative programming language, now with modules
was Stabel v0.2.0-alpha: A pure concatinative programming language, now with modules
Recording of the week: A Yanomami ceremonial dialogue
was Recording of the week: A Yanomami ceremonial dialogue
Stabel: A pure, concatenative and statically typed programming language
was Stabel: A pure concatinative programming language, now with modules
was Stabel v0.2.0-alpha: A pure concatinative programming language, now with modules
Technology Saves the World
was Andreessen: Technology Saves the World
Why bother with old technology? (2013)
was Restoration of vintage computers – Why bother with old technology?
What Happens If an Astronaut Floats Off in Space? (2013)
was What Happens If an Astronaut Floats Off in Space?
Legal expert says Tether and Binance Coin are likely picks for SEC lawsuit
was Legal expert says Tether and Binance Coin (BNB) are likely picks for SEC lawsuit
If you think psychological science is bad, imagine how bad it was in 1999
was If you think Psychological Science is bad, imagine how bad it was in 1999
Six charged in Silicon Valley insider trading ring
was Six Charged in Silicon Valley Insider Trading Ring"powershell for unix", "structured pipes", "pre-parsed text", "small, useful, typed tools loosely coupled."
- Typed object streams, which gives you stuff like autocomplete, IDE support, and generally there's no need to muck about with sed/awk/xargs - Very fast, it's absolutely fine to read a file line by line, and parse it in a script, whereas doing the same in bash/awk is a ton slower than clever use of cat/grep/wc (and a myriad of other tools) - Due to type information being retained, it's a lot easier to figure out what a given script does, without having to know how the output of a given tool looks like, given it's particular command line switches.
This is just my opinion, but PowerShell is a lot more geared toward people like me, who only write a script once in a blue moon/muck about with the build scripts occasionally, while Bash is more geared toward veteran sysadmins who live and breathe this stuff.
Or it follows the opposite mentality and the sell comes with batteries included?
I'm thinking of some arbitrary example, like downloading a JSON and parsing it to obtain some nested sub-property. In Bash world you would use the shell to execute at least something like `wget` to do the download part, and then run `jq` to parse the JSON and select the desired property. Both of `wget` and `jq` are independent programs, installed separately, with their own input & output channels, that you combine together by using the shell itself.
How would this work with PowerShell? (feel free to use some other example that might be better suited)
powershell offers cmdlets which let you sort and filter these result objects based on object property values rather than sorting on plain text values.
Obviously when printing to stdout or stderr, THAT bit is plain text, but until that very last step of displaying in the terminal, powershell results are objects.
So, that gives you a form of type safety, which isn't strictly possible in text-only shells. Powershell uses reflection to inspect the objects since the exact type of a response may have never been seen before. You can write your own cmdlets which return your own types and you can modify types returned by cmdlets using operators like 'select'. So, it's type-safe but not like everyone is used to. Powershell cmdlets always return objects (or errors, I guess), but the structure of those objects isn't always known until runtime. You can still use those never-before-seen types with the standard operators like sort and select, too.
Powershell also offers output conversion cmdlets which let you output to CSV or a textual table or a list, which is helpful when the next step in your pipe chain is a tool that expects textual input or a csv file. One can also write their own output formatters, of course.
In those ways, powershell and nushell appear to have the same goals. I haven't looked at nushell any more closely than it would take to notice this, so there may be other similarities I haven't noticed, yet. I'm sure there are many differences that I haven't noticed yet, as well.
To download json over rest you would use Invoke-RestMethod or irm.
To convert json to objects you would use ConvertFrom-Json.
To select properties from objects you would use Select-Object or select.
Here is a concrete example that I wrote for the rustlings install script: https://github.com/rust-lang/rustlings/blob/main/install.ps1...
Note that I used Invoke-WebRequest instead of irm here.
On linux...it seems both redundant and just plain weird for weirds sake. There are literally dozens of alternatives on linux that have a sane syntax and are likely preinstalled.
It's not a good interactive shell environment though. The commands are way too verbose and the syntax feels clunky for keying in.
[0] tab complete works on cmdlets, switches, and variables.
Same for switches and parameters. You don't have to miss `rm -rf foo/`, it's just `ri -re -fo foo/`
The module system is also not great for distributing little configure snippets like Oh My Zsh or something, it's clunky and over-complicated for that.
Isn't this how modern tab complete works everywhere? bash 5.1 (the shell I happen to be running right now, and which I mention because I think of its out-of-box tab completion as pretty basic) tab completes variables.
We use it for automation in our .NET codebase (which is being developed on both Windows and Linux) instead of bash scripts because of that and the fact it's preinstalled in the .NET SDK Docker images
The only PowerShell tool I did love was posh-git [0]. Thankfully, someone has ported it to bash/zsh as posh-git-sh [1].
docker network inspect webservers -f '{{ range.Containers}}{{.IPv4Address}}{{end}}'
Once tools start down this path, I think powershell, or any shell built around primitives that work on tree structures, make more sense (ie: rather than cut, awk, grep-tools for printing named fields etc).Must admit, I am no big fan of ps syntax - too verbose for interactive use - too unfriendly for scripting..
Also if you are managing Azure from Linux or macOS.
The unix way of text streams and tools to manipulate them are too ingrained that I haven't bothered to get in detail, but I hear some people are fans.
It's hard for me to criticize it because I haven't used it, but it looks like it was designed by a committee and overdesigned. I.e. it wasn't created from the need, like someone at Microsoft wanted to automate his work and created PS to solve his problem. It looks like some boss decided: "They have shells, so we should have it also. But we will make it much cooler. So, let's gather a committee of 500 of our best managers and let's decide what features it should have".
It looks artificial and inconvenient to me unlike Unix shells. Maybe I'm wrong. But I'm pretty sure that even syntax of PS makes it harder to type the commands. Unix commands are very short (many are 2-4 letters long), all lowercase and do not contain characters which are hard to type (e.g. `-`).
Part of why PowerShell may seem not quite Unix-like, is Snover didn't just look at Unix as an influence. Snover's professional background included experience with IBM OS/400's CL shell and OpenVMS's DCL, and his experience with both systems influenced PowerShell's design.
The idea to tie it with .NET and COM+ on windows is the best a shell has ever done, though someone noted in another thread that it is an old idea from XEROX mainframes (not sure what the name was).
if you want to imagine this in terms of unix/linux - it would be something like having all libraries' APIs at disposal directly from a shell that passes structured objects. or python's REPL being more shell-usable or JVM having a shell that provides access to all classes in a click of ENTER.
major downside of pwsh is that you can feel it being slower than expected due to the way objects are passed around, but I really expect this will be solved at some point with future releases as PWSH as language is still being developed so some concepts and internal architecture decisions perhaps change a lot.
noshell is taking this idea to a fair level, but really, there is a reason to do some dev/devops work in PWSH because it will heavily impact all future shell development even if eventually superseded by something better.
But what's the "business case" for iteration, conditionals, addition - apart from "everyone needs these"? Though these probably weren't the features he was thinking of.
> I.e. it wasn't created from the need, like someone at Microsoft wanted to automate his work and created PS to solve his problem
Interestingly enough, it is used for automating Windows configuration.
Re last paragraph:
UNIX commands are random letters that are like that due to historical reasons — if you don’t know one exists, you can’t find it. And when you have to use {} in PS you are dealing with something you would do with awk sed with even more arcane syntax — PS is pretty readable with some knowledge on any PL. Also, they are Verb-Noun based so you can get around and find commands even offline (though Noun-Verb would have probably been a better decision). Due to the fixed syntax they can be shortened very well. Also, due to every “command” having the same conventions, arguments are properly done (no tar xf or -xf or —extract), they are reliably autocompletable without black magic, and they are also autocompletable by giving enough letters to make it unambiguous. So while I am not particularly fond of Microsoft, powershell is better than bash (though frankly, what isn’t?) in every conceivable way.
There are fair criticisms to be made of bash...but this isn’t a fair comment either; I use power shell a lot; I’ve written hundreds or thousands of lines of powershell glue for scripts and devops pipelines and all kinds of things.
It’s not very good.
It is one of those things that seems like it’s a great idea; everything is an object, don’t serialise between jobs, tab completion on related objects, verb-noun commands... it reads like a feature matrix.
The reality is less ideal.
It’s verbose, the commands are arcane, and the verb-noun thing breaks down into meaningless pairs in many cases, particularly in the azure commands, or worse sql server commands.
Maybe, to be fair, there is a core of elegance in there, but powershell displays a fundamental failure:
When an application doesn’t have to do the hard work of making a good cli, the resulting commands in powershell are actively user hostile.
It’s a pattern I’ve seen over and over again; and things like the az-cli are a tangible acknowledgment from Microsoft itself that the results have been substandard, and rejected, overwhelming, by the broader community in favour of arguably inferior tools (eg bash).
So... you might argue “network effect”, but I don’t buy it; powershell isn’t friendly; not to new developers, not to “clicks ops” developers, not to Unix developers.
It’s firmly a middle ground “no one wants to use it if they can avoid it” product.
Bash scripts, now there is literally a hell on earth... but bash itself? Works fine.
/shrug
No way, I love PowerShell. It was my first choice for the bulk of a B2B Windows integration product. Part of it's a C# desktop app; the rest is PowerShell scripts that customers can edit to taste.
I reach for it all the time in projects. The pipeline is so clean to work with. Once you get used to how it handles collections, the cmdlets are very intuitive, and PowerShell Gallery has a large selection available for download.
Objects instead of strings is big by itself, of course. Then you get the .NET standard library right in the shell to interact with them. Great for parsing dates, numbers; a powerful regex engine; stream manipulation; pathing functions; the ability to write and execute C# in the shell; etc.
The cmdlets for data manipulation have gotten very good, too. The CSV cmdlets used to be unintuitive because they exported type data, but that's now off by default. `Import-Csv` and `Export-Csv` work with objects that you can easily manipulate with the set operations cmdlets. It feels very much like LINQ.
Same with `Invoke-RestMethod` (`irm`) when interacting with APIs. It deserializes JSON into objects automatically. You can then easily filter or transform the result.
There's a learning curve for sure, but once you get past that, it's a very good shell. I feel like it's one of the best things to come out of Microsoft.
It's just that I feel uncomfortable even looking at the PS syntax. Maybe it's idiosyncratic. Maybe I've spent too many years in Unix shell.
The only reason anyone accepts it is that it has always been there. But if you actually look at it critically, it is hot garbage.
Another great feature is named parameter support. It's so much easier to deal with parameters than with other languages I've used.
The thought process was more like "You can either hire a dude to do it by mouse in MMC or you can get someone with a masters in CS to do it in DCOM. We need a middle ground."
Source: was in the room
MMC can control remote computers, but I believe only one at a time? Unless it's something through Group Policy.
Now, the APIs exist to do all this remotely (DCOM), but good luck discovering what they are! And the minimum level of program you'd need to call them would be a C# project.
So, Microsoft knew that UNIX systems had an API that was interactive, scriptable, discoverable, and composable, all the things which CMD and MMC and DCOM aren't. So they decided to build one. And make it object-orientated. It's actually pretty good for the administration use-case, but for more general work it feels weird. And it doesn't interact with text files anywhere near as good as shell does.
First of all your backstory is wrong, it was a 1-person project. Then, about the features, all those long, explicit commands have short versions.
Secondly, I agree that Powershell feels a bit alien on Unix, which will probably be the main reason its adoption will never be amazing.
In general I really dislike "[some other product] for [a different use case]". It might be accurate but many potential users might never have heard of PowerShell or if they have only have a vague idea of what it is.
It's not hard to imagine the same for PowerShell.
1. parse a json value from stdin and set it as the initial result
2. for each function, apply the function to the result, and set the output as the result for the next function.
3. The final result is pretty printed on stdout.
Sum types (and pattern matching), first-class results, ownership, good performances and a rich ecosystem turn out to be quite nice for a general purpose langage once you’ve passed the hurdle of the borrow checker, even ignoring all the zero-cost abstraction stuff.
Also the really solid and safe multithreading. You might struggle a bit getting all your ducks in a row, but past that you’re reasonably safe from all sorts of annoying race conditions. And rayon is… good.
Not sufficient for GUI applications where the rust experience remains not great, but for CLI or even TUI?
I’ll misquote something i recently saw on Twitter because it’s very much my experience: “and once again I end up riir-ing a one-off tool I wrote in python and wonder why I didn’t just do that from the start”.
1. Haskell: had to deal with cabal hell
2. Scala: Java toolchain, VM startup time, dependencies requiring differing Scala versions.
3. F#: .NET was considered too Microsofty to be taken seriously for cross platform apps.
4. OCaml: "That's that weird thing used by science people, right?" - Even though Rust took a decent amount of ideas from it, it got validated by its early users like Mozilla and Cloudflare, so people felt safer trying it.
5. Lisp: I don't think I need to retell the arguments around Lisp. Also a lot of the things Rust touts as FP-inspired benefits around type systems really aren't built into lisp, since it's dynamically typed, these come more from the Haskell/Scala school.
Rust feels like the love-child of part of ocaml (for the sum types), part of C (very small runtime, ability to generate native code, interrop with C libs, etc..), part of npm (package manager integrated with tooling, large discoverable list of libraries), etc...
Borrow-checking seems a bit newer-ish - but I'm pretty sure there is an academic FP language that pionnered some of the research.
No-one is planning to give Rust the medal of best-ever-last-ever language any time soon.
And none of that is a "bad thing" (tm.)
In relatively familiar package & paradigm, with great package management (Haskell is the best of the functional langages there and it’s a mess), and with predictable and excellent performances.
Putting this together makes for a nice environment to distribute native system tools. And in the last few years we've seen a wave of these tools becoming popular (ripgrep, bat, fzf, broot, exa and some others).
"It's so easy!" yes if you have the language and tools de jour installed and up to date. I want none of that.
It was node and npm.
Then go.
Now Rust and cargo.
Oh, I forgot ruby.
And all this needs to be up to date or things break. (And if you do update them then things you are actively using will break.)
I don't need more tamagochis, in fact the less I have, the better.
What happened to .deb and .rpm files? Especially since these days you can have github actions or a gitlab pipeline packaging for you. I can't care less what language you are using, don't try to force it down my throat.
How dare people writing cli tools not package them conveniently for my distro. The horror of using cargo instead of cloning the source and praying make/meson/etc works.
Feel free to package and maintain these tools yourself for your distro if you want.
The problem with those is they require global consistency. If one package needs libfoo-1.1 (or at least claims to), but something else needs libfoo-1.2+, we can't install both packages. It doesn't take long (e.g. 6 months to a year) before distro updates break one-off packages.
I think some people try hacking around this by installing multiple operating systems in a pile containers, but that sounds awful.
My preferred solution these days is Nix, which I think of as a glorified alternative/wrapper for Make: it doesn't care about language, "packages" can usually be defined using normal bash commands, and it doesn't require global consistency (different versions of things can exist side by side, seen only by packages which depend on them).
The concept of a language-specific package manager distributing not only libraries but also executables isn't new. Go get, ruby bundler, python pip, cargo and npm all have this feature.
I was originally answering a question about why we suddenly see all these "written in Rust" tools pop up. I think that is partly because Cargo provides this easier way to distribute native code to users on various platforms, without jumping through additional hoops like building a .deb, and setting up an apt repository.
Sometimes you just want to get some code out there into the world, and if the language ecosystem you are in provides easy publishing tools, why not use them for the first releases? And if later your tool evolves and becomes popular, the additional packaging for wider distribution can be added.
As it stands, I can brew install ripgrep and it just works. I don’t need to know it’s written it rust. If, for some reason, homebrew (or whatever other package manager) is lagging behind and I need a new release now, cargo install is a much easier alternative compared to, again, other tools built in equivalent languages
I'd love that to all be "one-command automated", but I haven't seen such a thing, unlike cargo, which I do find I can be productive with after a one page tutorial.
Run "cargo install myProject"
I know Rust, so Cargo is not alien to me. But come on, you know that your install instructions are a bit shitty.Please, choose a target distro, then test your instructions in a clean Docker container. THEN you can sit down knowing you wrote proper guidance for users.
EDIT because this comment is being misunderstood: I meant that you should make sure your instructions work as-is from a clean installation of your intended distro(s), regardless of how you prefer to do so; using a Docker container is just my preferred method, but you can also do a clean VM or whatever else, as long as you don't assume anything beyond a default installed system.
Once cargo/cmake/autotools/make/npm/mvn/setup.py/whatever runs, the process of taking the output and packaging it for your preferred distro is the same.
There's more work involved if you want a distro to actually pick it up and include it in their repos around not using static linking, but if you're asking for a .deb/.rpm on github actions, that's not needed.
Rust isn't an interpreted language, you only need the rust toolchain if you want to build from source.
// I can't care less about deb or rpm files so don't try to force that down my throat.
I'd say the closest are Go, which doesn't have remotely as good a type system, Typescript which isn't compiled and isn't quite as fast or nice.
Achieving mastery in C++ requires a lot of work. C++ projects require a coding standard. The decision space you have when working in C++ is much larger than when working with Rust due to the proliferation of language idioms.
Rust in the other hand, as a newer language, can benefit from the experiences working with languages such as C++, and provide a better experience right from the beginning. In fact, Rust was created by Mozilla as a response to the shortcomings they perceived in C++.
Ready for the downvote wave. :D
It’s fine if writing systems languages doesn’t appeal to you, but they fulfil an important niche in. V8, Hotspot, Cpython all have to be written in something.
Why you think it is "a big deal"?
So, reducing security bugs means less crashes on weird input, less leaks (better resource usage), just a more stable tool as some classes of bugs (which may or may not be security relevant) are just eliminated completely - that's a big deal as with rust the (runtime-)cost other languages avoiding this is just not there (or much smaller).
Security is like the issue now, along with reliability. That's what people need and want. Rust offers that.
In the past it has been Lisp, Python, Haskell, Go, etc.
There's also no support for variables yet if the page is to be believed, which means there's 0 chance of me using this for more than 5 minutes right now.
(I'm not trying to say this project isn't worthwhile, just that many other people in the thread currently seem to be entirely uncritical.)
There's HN-style nitpicking, and then there's this.
My initial interpretation is that this is a level beyond typical nitpicking, but I'm not sure how that follows?
Calling his marketing line "disingenuous" comes across as very petty nitpicking that adds nothing of value to the discussion.
The part that bothered me was not that they described something that shared some concepts with PowerShell as "a new kind", but that I did not see any illustration of entirely novel features in the examples that followed. As a sibling comment remarked, they feel I'm quite mistaken, and there are very positive distinctions illustrated in the examples, but I took a look at them again, and it's still not clear to me what they mean.
I think I don't see why it's unreasonable for something which advertises cross-platform support to be compared to common shells on all those platforms, not just originally-*ix ones? That is, I think it's totally reasonable for you to think the tagline is justified solely by the differences in those shells, even if I disagree, but I don't see why you think it's unreasonable for me to hold this view?
"Nu supports variables and environment variables"
My muscle memory for bash is pretty strong, but when I have to do Windowsy stuff, I end up picking up a little bit more Powershell each time and find it pretty neat.
So I'd be interested to know what it does differently, and couldn't find that answer.
I see minor syntax differences, for example in the comparison operators. Nothing that would it would be worth losing the .NET BCL or PowerShell's cmdlets for.
Could you provide an example of what I'm overlooking?
I also think it's reasonable for people to say it's justified - there's certainly, as you and others have remarked, a decent argument to be made for that.
But for me, "different from many common shells, but all the same functionality has been bundled in one shell before"* strongly violates my expectations for "new kind of shell".
* - I am not trying to definitively state they have no new functionality, I absolutely have not dug in deep enough, just that I did not see any examples of it, which I would have expected prominently.
You could probably point to just about any technology that claims to be new and pull it apart and find that it is mostly derivative of existing technology and ideas
* "all these ideas have been done before, in various places" is one thing, "all these ideas have been done before in one program in the same role on all the same platforms" makes me feel like "new [to users who haven't used this other thing shipped with the OS for years on one of the platforms]" is insufficient to use without more explicit qualifiers
* I may be oblivious and missing some cool example, but the flip side to "all ideas implemented before" is "no new tricks", and when someone describes something to me as "a new type of X", I really expect at least one novel thing or composition of things to be present.
After all, I wouldn't describe TIFF as a "new type of image format" just because many people who haven't touched photo/graphics editing probably haven't encountered it, or IE4 as "a new type of web browser" (now) just because a significant fraction of internet users are not old enough to have used it when it had market share. (When it was first released, Active Desktop, for example, while a security nightmare, was indeed a new thing for almost all users.)
> Philosophy
> Nu draws inspiration from projects like PowerShell, functional programming languages, and modern CLI tools. 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. These values can be piped through a series of steps, in a series of commands called a 'pipeline'.
We would be able to use standard pipelines and jq to filter/query outputs, without any custom shells.
Just imagine:
ifconfig --json | jq '.[] | [.interface, .inet] | @tsv'It's integrated into a lot of FreeBSD's command line tooling, and is very useful, when it's available.
Ed: I'd say from a quick glance that I think I rather prefer nushell to powershell
I recently switched to zsh with the addition of oh-my-zsh and I am happy how it has features like auto completion and command validation of some sort, but this could take it to the next level.
I am just afraid to change to it and be disappointed about some incompatibility issues or bugs / crashes.
I will observe and wait until it's quite popular to hop on I think.
I tried it ~7 years ago and thought it was severely lacking, so I just stuck with zsh and have never really had a reason to look back.
Maybe I'll check out fish again at some point - what features does it have that drew you to it?
1) the autocomplete suggestion as you type a command [1]
2) scrolling thru commands after partially writing one only shows entries that match the written text
3) knowing if a command will work before pressing enter -- saves from a lot of gotchas.
all of these read like features nice to have but not essential, but when you're using something every day, it's worth it :)
[1]: https://fishshell.com/docs/current/tutorial.html#autosuggest...
The main reasons were:
1. It had a lot of qol features I liked from zsh _by default_ without requiring a significant config
2. Prebuilt zsh configs like oh-my-zsh have been pretty commonly quite slow in my experience, which fish fixes.
Either update automatically in the background or don't tell me about updates at all. Don't constantly nag me when I start new shells!
[0]: https://github.com/tasuki/dotrc/commit/e3769134e758d02a947ef...
Give prezto a try. You might like it.
Sometimes the new ways are best...
I often find that redesigns / rewrites can be transformative. The same benefits less often accrue to incremental changes.
Practically, in my experience, when a group (or organization) is not under a severe time and budget crunch, redesigns seem more palatable. The results are more likely to be simpler, even if they are not as familiar.
That's how I generate much of the https://www.oilshell.org/ site. It's just a tree of files and various shell commands, some of which I wrote myself.
I do think we need something better than CSV and TSV for tabular data though. They both have serious flaws (not being able to represent values with tabs, etc.!)
For anyone confused by this, 1 is the output to stdout, and 4 is being redirected to where 1 goes, which is stdout. Unrelated to that, 1 (what’s actually being output to stout by the application) is being redirected to /dev/null.
The order of operations matters. If 1 was redirected to /dev/null first, then 4 would also end up in /dev/null. As it stands now, that doesn’t happen.
Maybe I should give PowerShell Core a try.
'nushell is basically a powershell something' 'bash/zsh is better/worse than pwsh/etcshell'
this is very unfair because pwsh allows control over of the all .NET/COM+ available in a system (well, .NET Core only on non-MS, but still).
while nushell stands on its own shoulders or if u like - allows control of other programs executed, but would not easily call into any API that is a language-specific one nor parse its output as structured one.
so when comparing bash, zsh, nushell, pwsh one should take into consideration that these have different foundations and goals even. like perl stands on top of CPAN, all the JVM stuff on top of all classes, etc.
although it is difficult to say why no one has created (to my knowledge) reasonable JVM-based shell, nor a python-based-one, since java targets such a large number of OS/platforms and provides such a broad library. perhaps because people assume that a shell program should follow the UNIX concept of one-program-does-one-thing-only. on the contrary - it would be a killer feature to have nushell be able to natively execute java/python/whatever API calls and use the structured output (like pwsh indeed).
in essence - is very limiting to compare bash to pwsh only in the sense of 'how much can be done with only few characters', because this always leads to very opinionated and biased arguments and eventually discussions taken out of context.
[1] https://xon.sh/
Basically a "cols" command on steroids - making that have some kind of context aware column names (I'm not sure how) and then support expressions would make it work in any shell.
In nushell one can just do `ls | sort-by size`
I also like that nushell's table oriented approach displays the column names, and you just use those names for the `sort` command or `where` command etc.
The README doesn't mention it at all, just that the tool is inspired by PowerShell.
Even if it goes mainstream it will be decade behind PowerShell in conceivable future.
While I appreciate the enthusiasm for developing shell, nothing usable here in years to come IMO when I can just use pwsh.
nu -c "ls | where size > 10b"May I ask if you switched to fish from zsh? What motivated your change?
Background: I invested some time not too long ago to read zsh docs in detail and customize my own configuration (e.g. instead of using oh-my-zsh). Since then, I've been quite happy with zsh. That said, I'm also open to switching to fish and/or nushell based on recommendations.
I’m happy with fish, and I don’t see much benefit to switching to nu. nu is exceptionally good at one thing: working with data, but lacks features in other areas (auto-completion, scripting, etc.). With time, I can see these features being implemented, but I think they’ll be re-inventing the wheel in a lot of areas that other shells are already good at.
didn't switch from zsh but bash, did it because wanted a bit more features at shell without additional configuration
As for the future, perhaps a bit brazen, but I’m confident that other shells will introduce the core feature of nu in the near future to stay competitive. I can see fish having a “||” operator and rewrites of a few gnu functions to achieve what nu does natively.
Anecdotally, I found switching shell to be more of a challenge than expected - I’ve been using (oh-my-)zsh for years and decided to try fish, but all the little differences were too annoying for me to get used to - I guess you build up a lot of “muscle memory”! That said, I probably just use the same commands most of the time. If you were doing more advanced stuff maybe it makes more sense to invest the time
(And the various other new shells, documented by the author of another new shell, Oil: https://github.com/oilshell/oil/wiki/Alternative-Shells)
Tangent: How is this at the top of the front page with a dozen upvotes and no comments? Maybe these upvotes all occurred at once?
$ nu -c "sys | get host.name"
> UbuntuIt would be ideal to me if it were a tool that could be piped into.
However, that's not to say I won't at least give it a try these days, since I'm really curious about it.
Dev: I have decided to stop working on this project thanks for all the support. If anyone wants to take ownership of it I am willing to transfer its ownership. (Crickets)
Me now after using it for a couple of years have to go back to standard bash or whatever and now people think I have no idea what I'm doing since I forgot so much stuff from lack of daily use.
'Let's make something complex appear intuitive by adding more complexity'.
I really respect the work that has gone into this project, but no thanks.
Compared to other modern alternatives, NGS is "programming language first".
Repository of scripts written in NGS, aptly named "NGS Scripts Dumpster" - https://github.com/ngs-lang/nsd
Context: https://twitter.com/cmuratori/status/1401761848022560771
The solution is to use the full path if you want to use the program, not the shell built-in.
In this case, "/usr/bin/open" not "open" will get you the macOS utility. If you get sick of doing that, create a shell alias.
The inbuilt commands and structured philosophy is a great approach.
I can see the evolution now. "nushell". Next iteration: "nuer shell" (newer) or "renushell" (renew)
This makes nushell an interpreter command line, instead of a system shell.
(Yes, you can "escape" by typing ^ before a word. That's not nearly the same thing.)
"If a command is unknown, the command will shell-out and execute it (using cmd on Windows or bash on Linux and macOS), correctly passing through stdin, stdout, and stderr, so things like your daily git workflows and even vim will work just fine."
Clearly I hadn't tried nushell -- this feature I thought missing was a big no for me. I have now, and this is definitely worth a try. Thanks all!
Curious what you tried that didn't work.