Brian Lovin
/
Hacker News
Daily Digest email

Get the top HN stories in your inbox every day.

stoplying1

I just ported a bunch of scripts to nushell.

I hit some bugs, a couple of which are a bit sharp, but wow, the list of quirks I have to remember for nutshell are so much fewer than for bash.

Constantly impressed at the errors it catches at parse time, kinda crazy sometimes.

Oh my god I could cry, strings are sane to work with. I may never write a bash script again (it's okay, I use Nix so I get nushell everywhere I'm might need it, for free)

Everyone is asking about PowerShell. I never hated it, but lord it makes some awful, stupid infuriating decisions. I've lost hair and sanity to some stupid list/single-item-list beahvior. Numerous operators and bits of syntax are just different. Everything about the script syntax is just slight odd and confusing. There's basically none of this with nushell. Jonathan Turner is a gifted person with an eye for language design and it really shows.

Edit: I do think it's missing some important output redirection functionality. You can workaround by using "complete" but that feels non-ideal.

mustache_kimono

> I may never write a bash script again

I wrote 2x 200 line-ish shell scripts recently, and it was simply terrible, and although I'm increasingly convinced we need a shell like abstraction, I can't believe `bash` is the best we can do. Really hope I find one of these alt shells that suits me. Not a fan of Python but xonsh looks really cool too.

nerdponx

Bash is not the best we can do!

If you want a traditional Unix-like shell that is mostly sensible in the places where Bash is not, check out Zsh. It has a ton of complicated features, but most Bash scripts can be ported easily (if not outright copied and pasted). Zsh has fewer footguns by default than Bash, and it has more "safety" settings that you can enable.

There is also the Oil shell, whose creator often posts on HN, and which I think is meant to be a superset of Bash, but I have not used it myself and can't vouch for it.

As for the alt shells, I've was specifically interested in Elvish, but I dropped it as soon as I saw that they don't support parameter interpolation in string literals, like `"${HOME}/.local"`. This is such a common operation in shell scripts that I have no interest in a shell that doesn't support it, and I can't imagine why Elvish doesn't.

nextaccountic

I would recommend Oil!

http://www.oilshell.org/release/latest/doc/idioms.html

It removes the need to quote every variable, and this is fantastic

anthk

>If you want a traditional Unix-like shell that is mostly sensible in the places where Bash is not, check out

PERL. Sh, awk, sed and mini-C all at once.

nerdponx

Since I can't edit my post anymore, here are some additional thoughts:

Traditional shell scripting languages are great at exactly three things: typing commands interactively, running other programs, and sourcing other shell scripts. They are also is distinct in that they are "stringly-typed" (i.e. everything is a string), and moreover that syntactically bare symbols are also strings.

Typing commands interactively is essential because... it's a shell. That's what it's for. Most programming languages do not and should not optimize for this. But it's literally the purpose of a shell, so a shell should be good at it.

"Running other programs" includes invoking them (literally 0 extra syntax), piping them (one letter: |), and redirecting the standard input and output streams to files (>, <, <<, etc.). This is one of the great innovations of Unix and nothing holds a candle to its elegance and convenience, even if sometimes we get frustrated that pipes are "dumb" streams of bytes and not something more structured.

"Sourcing other shell scripts" practically isn't much different from "running another shell process", except that source'd shell scripts can set shell parameters and environment variables, which is an important part of e.g. the X11 startup system: the global /etc/X11/Xsession script sources the user's ~/.xsession script, so any environment variables set in the latter are propagated to the former, and thereby are inherited by the X11 window manager when it eventually starts. If you wrote the /etc/X11/Xsession script in any other programming language, you'd have to inspect the environment variables of the ~/.xsession process and "merge" those values back into the current process' environment.

On being stringly-typed, I think it's mostly good in the context of the "two things that it's good at" described above. It cuts down on syntactical noise (otherwise "everything" "would" "always" "be" "quoted" "everywhere"), makes string interpolation painless, and generally supports the "typing commands interactively" use case. Make and Tcl are the only other popular languages in this category. Perl and Ruby allow it in specially-delineated areas of code. Moreover, Bash, Ksh, and Zsh all have arrays, which helps fix some of the biggest problems of everything being a string.

In short, if your program can make good use of the above features, then a traditional shell is a great choice. If you program does not need those features, do not write your program using a shell script, because shell languages are awkward at best in pretty much all areas.

And if you are considering an "alt" or "neo" shell language, in my opinion it must excel in the above two categories. Being stringly-typed is a matter of taste, but the language should also probably support bare-symbols-as-strings and string interpolation.

Python, for example, is not a good shell scripting language because it is not easy to type nontrivial commands interactively, it lacks tidy syntax for input/output redirection (even though it's actually pretty easy using the standard library), and it lacks bare-symbols-as-strings. So instead of:

    #!/bin/sh
    foo -x 1 -y 2 "$ABC" | bar --json -
you have to write something like:

    #!/usr/bin/env python3
    import os
    from subprocess import Popen, PIPE, run

    foo_cmd = ['foo', '-x', '1', '-y', '2', os.environ['ABC']]
    bar_cmd = ['bar', '--json', '-']
    with Popen(foo_cmd, stdout=PIPE) as foo_proc:
        foo_proc.stdin.close()
        run(bar_cmd, stdin=foo_proc.stdout)
You can of course write your own library that abstracts this and uses symbols like > >> < << | to mimic what a shell does. Maybe that's what Xonsh is, I haven't looked at it myself. But this hopefully demonstrates why the base language Python is not a good shell, despite it being portable, being nearly ubiquitous nowadays, being relatively easy to use and learn, being "safe" in many ways that traditional shell languages are not, and having a huge and useful standard library.

fuzzygroup

I find the lack of string interpolation to be the one thing that kills me about javascript. The lack of it feels wrong and I can't get behind languages that don't have easy interpolation.

Yes Ruby has ruined me.

jackac

Elvish:

    $E:HOME'/.local'

pletnes

Xonsh is very posix/bash-like but you can call python functions in an integrated way. Even if you don’t love python it’s a more sane language than bash. I really like it but I’ve been using zsh for too long.

naikrovek

Bash is not the best we can do, but it is definitely the best that most people agree on.

I fear there will be no defacto bash replacement for many years.

exyi

What do you mean by "agree on"? We never agreed the programming language, which means ... that I can choose whatever I like.

Pet_Ant

Honestly I’ve enjoyed working with PowerShell for scripts to work for all developers on my team regardless of what OS they are using.

nerdponx

I wanted to like Powershell, but it is missing some features that I think are essential. For example, apparently checking the return status of an arbitrary command is not trivial, and there's no equivalent of `-eu -o pipefail`. Yes, I know `-eu -o pipefail` is imperfect too, but it covers most common cases. I also struggled badly to stop it from mangling the output encoding of my applications (no, I don't want a goddamn BOM, thank you), and the solutions I found all either had no effect or required me to write what looked like C# code embedded in my shell script.

jborean93

The upcoming 7.3 release had PSNativeCommandErrorActionPreference which was an experimental feature to implement pipefail https://learn.microsoft.com/en-us/powershell/scripting/learn.... It is no longer experimental and will be part of the actual release. This allows you to set `$PSNativeCommandUseErrorActionPreference = $true` rather than rely on `$ErrorActionPreference = 'Stop'` which does more than just treat non-zero rcs as a failure which is nice.

Otherwise for older versions you can just do `my.exe; if ($lastexitcode) { "failure code here" }`. It's not nice but certainly not impossible to do.

pie_flavor

nounset is Set-StrictMode, errexit/pipefail is $ErrorActionPreference = 'stop' with $PSNativeCommandUseErrorActionPreference = $true. With those you can try/catch, which is infinitely better than the $?-based approach, but you can also use $? without them. PSCore encoding is always UTF-8 without BOM; you can enforce that the script is running on Core with #Requires -Version 6, or pass ($content | Out-String) to New-Item's -Value parameter for a v5-compatible hack.

Arelius

> For example, apparently checking the return status of an arbitrary command is not trivial

You mean the fact that it gets put into the $LASTEXITCODE variable instead of putting the command directly into the conditional?

majkinetor

pipefail is trvial: $ErrorActionPreference = STOP

Its even better then that as you can fail individual commands with their -ErrorAction argument.

BOM is not there any more.

csdvrx

It feels very different from unix shell. I like them both!

I think Powershell more advanced ecosystem with a default output more like the sqlite tables of nushell would be wonderful: the objects handled by PS would be more naturally suitable to this, and would compose more easily.

beanjuiceII

yep been using powershell here too..great stuff

fragmede

> strings are sane to work with

Okay, I'll bite - how does it handle filenames with spaces and newlines in them? I have a strong case of Stockholm syndrome with bash because I figured out how to deal with the first one, but I'd love a system that deals with that sanely.

w4rh4wk5

I learned PowerShell some time ago. I really like the concept and the power that comes with it. But, coming from Bash, I can't get a grip of the syntax.

I am in the process of switching most of my shell scripts over to Python; I wonder whether nushell would be the better option.

rileymat2

You are absolutely not alone with this. There appears to be so much power so much potential, but it /feels/ so awkward syntactically.

ripley12

> I do think it's missing some important output redirection functionality. You can workaround by using "complete" but that feels non-ideal.

Yeah, this is a very fair criticism. We're working on it :)

gatane

bash + lua, and life is good again.

SighMagi

How do you use bash and lua together?

WastingMyTime89

Should probably be switched to the official project page rather than a subpage on an unrelated party website: https://www.nushell.sh/

It’s a lot better at introducing Nushell and feels like a proper landing page.

eatonphil

So HN is not supposed to allow blog posts about projects but must always swap out for the project site itself? As someone who writes blog posts about projects, I hope not! It's not like this blog post is affiliate spam.

marcosdumay

If the project site is better written and has the same content, yeah, I would prefer to see it.

But this is not the case here.

WastingMyTime89

Deeply disagree. The linked page barely introduces what the tool is. The part above the fold is an unrelated bio and the what is paragraph actually talks about what it’s not while barely explaining what it does.

The project page is better in any respect. I was going to dismiss it and was writing a comment about how the landing page should be improved before realising it was just a blog page. That’s why I’m linking it.

libria

These are 2 different types of posts.

1. A new product

2. An independent party's pro/con opinions about that product

This thread is about #2. If you feel #1 has value on its own, post that.

Read both your link and the OP's. While the topic is the same, the content is markedly different.

forgotpwd16

Better not. In this case the blog post provides more complex and interesting examples than the simplistic ones on the official page.

solene

Isn't https://www.nushell.sh/ the official website?

JW_00000

It's a blog post but somehow the styling doesn't make it look like one.

rodorgas

It doesn’t need to be switched, you can submit the project page anytime.

undefined

[deleted]

wkdneidbwf

haha, thanks for this. i was looking at the examples on the other page and was like, "jfc, no thanks"

eatonphil

It's someone's personal blog post. No need to be mean. The styles are a little brutalist but also readable to me.

wkdneidbwf

i wasnt talking about the css…

i mistook the blog for the an official introduction and was turned off by the complexity of the examples. which i stand by—that’s a poor introduction to the shell.

cyber_kinetist

I use it as my primary driver, for the sole reason is that it's the only cross-platform shell that properly supports Windows (without resorting to Cygwin/MSYS, which has performance issues and many pain points). I'm still getting used to the syntax though...

(Edit: forgot to mention Powershell, since nowadays it also works on Macs and Linux)

deafpolygon

Why use this over PowerShell for example?

cyber_kinetist

Well, it is a good point, since nowadays PowerShell is also cross-platform, and seems to have more features than nushell does.

Though the true reason is: I haven't really found the time to. Changing a shell is really stressful since you have to unlearn / relearn lots of things from muscle memory, and PowerShell's huge deviance from the rest of the POSIX-y world doesn't help. At least in nushell `rm -rf` works, the same doesn't in PowerShell.

delta_p_delta_x

> PowerShell's huge deviance from the rest of the POSIX-y world doesn't help

In PowerShell (on Windows), `rm` is an alias to `Remove-Item`[0].

Therefore,

    rm -r -fo <thing>
An extra dash, extra space, and extra letter isn't too bad by my books. Furthermore, in scripts, aliases are discouraged by PSScriptAnalyzer[1]; IDEs (PowerShell ISE, VS Code PowerShell extension) also support code completion, so:

    Remove-Item -Recurse -Force <thing>
makes things clearer.

[0]: https://learn.microsoft.com/en-us/powershell/scripting/learn...

[1]: https://github.com/PowerShell/PSScriptAnalyzer/blob/master/d...

sixothree

I am a C# programmer at heart, and I use powershell a good bit. I can honestly say I can never use powershell without my cheat sheets or my list of favorite commands (and especially the arguments to use).

I looked at this and kinda get it and think I could do some things with it. I don't think it's as powerful and can _definitely_ say it won't be capable of the same automations we use.

That said, the text parsing people do with bash makes me cringe. It's so repulsive and sketchy. Anything to get linux world off of bash would be a good thing.

vips7L

Do you use pwsh as your daily driver? I find that its commands are as easily memorable as any other shell.

That being said You should enable these:

    Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
    Set-PSReadLineOption -PredictionSource History
MenuComplete will give you a menu of arguments that each command takes so you can easily see them when pressing tab for completions and prediction source will try to predict the commands you want based on your history.

deafpolygon

I use pwsh as my daily driver, and the verbosity actually reduces my need for a cheatsheet.

What I'd love is for Powershell to _stop_ adding .\ to my tab completed files. Just quote it and leave it alone, unless it's an executable.

Once I got used to stuff parsing as objects, it's really hard to go back to everything-as-a-string in bash. I've gotten to writing a few personal scripts/modules.. processing stuff in JSON is just really nice.

ripley12

> can _definitely_ say it won't be capable of the same automations we use.

Anything in particular you think would be difficult/impossible in Nushell?

(I'm one of the Nushell developers, might be able to help or put features on the roadmap)

chasil

This is a common complaint among implementers of POSIX shells.

They are not LR-parsed languages, and cannot be expressed with yacc grammars.

Debian dash replaced bash as /bin/sh. It gains speed, but no better syntax.

https://archive.fosdem.org/2018/schedule/event/code_parsing_...

ripley12

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 a little 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.

pie_flavor

Something I've been curious about - are there any plans to sink serious effort into massively expanding the stdlib? Powershell's syntax and object-orientation I could take or leave, but access to the entire .NET Framework is pretty hard to beat, and the same draw exists for xonsh. Nushell is neat but there just aren't enough builtins.

stevefan1999

No need for (a minimal set of) dotnet runtime. This means Nushell can possibly run on slightly resource constrained environment such as Raspberry Pi, of course you don't expect it to run well with 256MB of RAM though. Also, Nushell is battery packed. For example, say bye bye to your Oh-my-ZSH because the features you have with OMZ (like shell autocompletion, suggestion, theming and formatting) is built-in in Nushell. I have also tried to parse `zfs list` output in my Proxmox machine that I don't want to use `zfs list | less` that often.

That said, I hope Powershell Core can be packed with dotnet 7 native AOT mode [1] so we don't have to screw around with 100 different MSIL DLL files to run a single shell...

[1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...

anthk

>of course you don't expect it to run well with 256MB of RAM thoug

I've run Perl scripts on 32MB...

cassepipe

It's dumb but I personally can't get over Camel-Kebab-Case commands. I hate typing Caps, and hyphens.

haltcase

PowerShell is case-insensitive, you don't need to type caps for variable/function references if you don't want to. You'll still have hyphens, but in an interactive shell (as opposed to a script) there are many aliases you could use that avoid hyphens (or you can make your own).

https://learn.microsoft.com/en-us/powershell/module/microsof...

forgotpwd16

It's more Unix-y. Smaller footprint, opens faster, short commands by default. Otherwise the PowerShell influence is vastly understated in project page and docs.

pletnes

Doesn’t xonsh run correctly on windows? I used it but hated the environment due to the lack of utilities on windows (it’s just a shell, not an environment).

BeetleB

xonsh (Python based shell) works fine on Windows. Been using it for over 4 years.

actually_a_dog

I'm curious what you mean by "properly supports Windows." Are you on a version of Windows that supports WSL2 (Windows Subsystem for Linux)?

cyber_kinetist

I really don't want to start up a separate Linux VM just to open up a shell. (I already crossed out Cygwin / MSYS on the list because of performance issues...)

cyber_kinetist

Also, I need to compile actual Windows binaries using the shell (MSVC, clang-cl), and I obviously can’t do that under a Linux VM.

chasil

Busybox for Windows has a very accessible shell.

pletnes

WSL is great but it’s basically a convenient VM. It’s no longer windows, as far as I’m concerned.

chem83

It’s a lightweight Hyper-V VM, just like Windows itself when you turn Hyper-V support on (boots hypervisor first, then the Windows VM in the root or parent partition)[0].

But if that’s an issue, WSL1 is still an option.[1] It’s a thin translation layer between Linux kernel calls and NT kernel calls, which was the original concept of subsystem from the early NT days which allowed OS/2 apps to run on top of ntdll.dll.

WSL2 didn’t replace WSL1.

[0] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-...

[1] https://learn.microsoft.com/en-us/windows/wsl/compare-versio...

sixothree

It's literally a subsystem. It's integrated in many ways you would not use to describe a "VM". I don't understand the aversion nor the confusion.

bsdetector

Having written a lot of shell scripts, the single greatest thing I've ever experienced is shell-friendly outputs.

For example, consider if ls had a "--shell" option that output each entry as a single line of shell-quoted variables safe for eval:

    # cd /usr/share/dict
    # ls --shell words
    path="/usr/share/dict" file="words" user="root" group="root" size=985084 ...
Then all sorts of things become easy.

    # eval $(ls --shell words); echo "$size" "$file"
This nushell doesn't really change anything important about this biggest scripting problem. You're still parsing human readable output and it's still dependent on particular versions and options passed.

If I had a genie wish of nushell being installed everywhere or even just coreutils having a --shell option I'd take the latter any day.

kazinator

Calling an external too to list files is an anti-pattern; every programming language or shell language should have that built-in, so it's just doing that via the OS API (opendir/readdir/closedir).

The POSIX shell has that in the form of globbing. That only gives you names, and has quirks that are only adequately worked around with Bash options.

The fix is to use some real programming language for complex work.

I made a language for myself in this space, geared toward C and Unix people who are willing to try Lisp: TXR.

  1> (stat "/usr/share/dict/words")
  #S(stat dev 2306 ino 884986 mode 33188 nlink 1 uid 0 gid 0 rdev 0 size 931708
          blksize 4096 blocks 1832 atime 1667315034 atime-nsec 0 mtime 1238396423
          mtime-nsec 0 ctime 1405615444 ctime-nsec 0 path "/usr/share/dict/words")
  2> (flow "/usr/share/dict/words"
            stat
            [callf list .path .size])
  ("/usr/share/dict/words" 931708)
  3> (flow "/usr/share/dict/words"
            stat
            [callf list .path .size [chain .uid getpwuid .name]])
  ("/usr/share/dict/words" 931708 "root")

com2kid

> Having written a lot of shell scripts, the single greatest thing I've ever experienced is shell-friendly outputs.

This is basically the idea of PowerShell. Output is well formatted data that can be passed around and manipulated in a regular manner. No slicing on columns or anything like that.

PowerShell has other issues (many of which are documented in these very comments!) but shell friendly output is one of its central ideas.

mastax

Well in nushell you wouldn't be using the coreutils commands, you'd be using the nushell builtin replacements. Those builtins return structured data.

Now for the 1000 other non-coreutils commands on your system, that's not very helpful. --shell is a good idea, though it seems like JSON is becoming the most common alternative structured output implemented by commands. Nushell and PowerShell can turn JSON into a structured variable easily, though using jq in shell is alright most of the time.

dkarl

jc [0] is dedicated to providing this externally for common commands, but I agree that it would be better if command authors built it in as an option. It would make shell scripts shorter, more readable, and less buggy.

[0] https://github.com/kellyjonbrazil/jc

d33

I like the idea, but if it was interpreted directly, that would be a security nightmare unless we also had something like Python's ast.literal_eval(). Which makes us come back to JSON-like outputs because we need some form of serialization anyway, I guess.

bsdetector

Of course there could be some tweaks like a scoped eval to prevent stomping on the script's variables, but it's really not very hard for a C program to escape shell variables correctly and safely.

You could have an eval that only read variables, but trusting a program to only return variables is a really low bar; it's very hard to mess that up.

SoftTalker

Part of it is knowing the tools. In this case, 'stat' is the command you probably want to get parsable details about a file, not more options to 'ls'. I often see convoluted shell scripts that could be a lot simpler with the use of more appropriate utilities.

bsdetector

It's just an example. With shell-friendly outputs you can recreate "ls -l" with any field order you want with just a few lines of readable shell script. Many of the unix tools only exist because it's so hard to parse the human-readable output in the shells.

eternalban

Wouldn't 'find .. -exec ' and friends get you this?

    find . -type f -depth 1 -exec ls -la {} + | awk {'print "file="$9 " user=" $3 " group=" $4 " size=" $5'}

kazinator

Your awk has to put out file="..." notation, and if double quotes occur, they have to be escaped. So you're looking at substantially longer command.

  | awk 'function esc(str) {
         ...
         }
         { print "file=\"" esc($9) " user=\"" ... }'

exyi

Many tools have some switch which will make them output JSON, which is easy to process if you have jq. For example `docker something --format='{{json .}}'`.

dloss

Its dataframe support (based on Apache Arrow and the Polars Rust library) looks very interesting. https://www.nushell.sh/book/dataframes.html

zozbot234

Yes, it really should be called Polarshell.

blahgeek

I still believes that [xonsh](https://xon.sh/) is the best of its kind because I do not want to remember yet another language syntax

gatane

Is there something like this but with Lua?

TheLocehiliosan

Just was trying it. A couple minutes in, I discovered it doesn't support suspended jobs.

:( seems like that would be a very basic feature.

https://github.com/nushell/nushell/issues/1329

https://github.com/nushell/nushell/issues/1796

https://github.com/nushell/nushell/discussions/5239

SighMagi

In the past, I've toured these alternate, non-POSIX shells like Nushell. A lot of them (e.g. Powershell, Elvish) don't provide job control. I looked into how job control works and it's kind of a bother, so I see why they might have elided it. I wonder if multiplexing the terminal using tmux or screen is a good enough alternative the job control for many use-cases. You do lose state (i.e. environment variables, working directory), but if all you want to do is run something else maybe it's good enough.

I personally haven't tried living without job control though.

Natfan

Sorry, but you're incorrect here. PowerShell does most definitely provide job control.

    Get-Help about_Jobs
Alternatively, online documentation from Microsoft regarding jobs: https://learn.microsoft.com/en-us/powershell/module/microsof...

SighMagi

I think you must be unfamiliar with job control, but I could be wrong. How do you Ctrl+Z a foreground job, maybe several, and then switch between them.

All of what “powershell” provides depends on knowing you want to background something ahead of time, and even then I don’t think you can make it the foreground task (maybe wait job comes close) There is even a Github issue on it, which I’m afraid I can’t be bothered to go find again

parhamn

My data point: I prefer tmux/multiplexing over job control because the process hierarchy leads me to managing them better (I never accidentally quit tmux). Also I don't have to worry about std stream usage. I'm actually not sure of a case I'd care for job control.

yencabulator

The problem with tmux is that I often start a long process without really realizing it, then control-Z bg to continue working with the shell. With tmux, I'd need to either realize up front I'm about to start a long-living thing, or lose the context of the current shell to continue my interactive work.

Myrmornis

I also use tmux for this. Personally, since starting to use tmux years ago, I've never even thought of wanting job control in an interactive shell process.

lisnake

You might be interested in Cat9, https://github.com/letoram/cat9

It's another reimagination of a shell, but built around asynchronous jobs

the__alchemist

Does anyone have an ELI5 for what this, BASH, ZSH, Powershell etc do? It seems it's a conflation of #1: A CLI. #2: A specialized programming language that mainly does file-system operations. Is there a compelling reason to use something like this (or Powershell's scripting system, from the comments here), vice Python or Rust's etc standard library filesystem tools?

Context: I use Windows Terminal with embedded powershell on Windows, and Terminal on Linux. Useful for compiling programs, running Python scripts, and executing CLI-based programs (eg clippy, ipython, rust, various programming-language-specific formatters etc, some CLI-based text editors like VIM). Also, troubleshooting Linux problems.

BoppreH

Shells are a combination of programming language, user interface, and standard library. The programming language and stdlib aspects are just like Python or Rust, but with a different focus:

- Terseness. I can very realistically type hundreds, if not thousands, of commands per day. Extra words or punctuation marks add up quickly.

- Shells are focused on executing things right now, as opposed to most other languages where the output is an abstract program to be run multiple times. This means using literals more often than variables, for example, which is why unquoted words in Bash are strings (except the first word of a command, because terseness is more important than consistency).

- They have more interactive features, such as warnings and prompts. Powershell detects if you're missing required params and prompts you one by one, for example.

- The purpose of a shell is to enable interactivity with OS primitives, be they Linux's files/processes or Windows' objects.

- Because most commands are typed interactively and only run once, glue code is especially painful and wasteful to write. So these languages pick a simple data structure for all function communication, and stick with it (e.g. Powershell's typed objects, Bash's newline separated strings, Lua's everything-is-a-table).

- Quality-of-life features. For example, Bash aliases (e.g. `alias wget='wget -c '`) are a pretty good idea that is non-trivial in other programming languages.

- Easy to plug stuff into other stuff. I don't mean just piping, but also things like temporary files via Bash's process substitution `<()`.

the__alchemist

Very clear explanation; thank you!

raydiatian

A shell is pretty much what you described. More accurately it’s a program for interacting with the operating system, and it usually ships with a scripting language, and Utility programs. Hence the conflation.

If you’re using Windows Terminal, you’re using a sort of predecessor to Powershell (somebody please correct me on this), if you’re using terminal on Linux, you’re most likely using bash. Enter ps -p $$ at your Linux terminal to find out (which shell you’re using).

> Useful for compiling programs, running Python scripts, and executing CLI-based programs

Yeah, so from here, it’s possible to automate those commands, if you wanted to. In windows you’re talking about .Bat or .Ps1 files. Shells are the language you use to write those scripts, and they typically ship with access to some useful (file/text oriented) commands.

The only problem is these shells were invented in the 80s 90s, and have awful conventions that make some people miserable enough that they go and write a new shell that tosses previous conventions out the window. And IMO they did a great job.

ripley12

> If you’re using Windows Terminal, you’re using a sort of predecessor to Powershell (somebody please correct me on this)

Not necessarily. Windows Terminal is just a terminal emulator; you can run any shell in it: cmd.exe, PowerShell, Nushell, bash, fish...

deafpolygon

And what a great Terminal emulator it is.

the__alchemist

Appreciate those details! And as ripley said, Windows Terminal is a housing for other terminals like Powershell or various WSL OSes, but has tabs.

zacmps

Yes, scripting languages all support both:

* A repl for performing common operations (moving around the file system, running programs, etc),

* A interpreted environment for scripting these operations.

The main reason to use these instead of Python/Rust is the ease of interfacing with other programs.

In Python, and most other non-scripting languages, spawning and interacting with external processes is quite verbose.

the__alchemist

It's verbose in Rust too; error handling; various types ways to handle the program's stdout/stderr etc.

norman784

One issue I have with nushell is that on macOS they use the `Library/Application Support` path for the config instead of the `.config` making it awkward, their reason is that the former is the correct path of application data, while none of the other CLI apps I use do this, every other app just points to the `$HOME` dir or `.config` dir.

I used it for a while but I switched back to zsh, maybe in the future when it has a stable release I try it again, was too much hassle to update the config on almost each release. Also didn't worked well with some utils I use that has specific initialisation for each shell (i.e. rbenv).

Otherwise nushell seems to be a good contender for an alternative shell.

pie_flavor

it is the correct path for application data. Configs go in ~/.config on Linux, ~/Library/Application Support on Mac, and ~\AppData\Roaming on Windows; some other tools doing the wrong thing isn't a reason for nushell to do the wrong thing, and your preference for nushell doing the wrong thing shouldn't mean I have to suffer it. If you want it to be visible in your home dir, you can easily put a symlink there.

norman784

When you work on multiple OSes (mainly macOS and Linux), having your dot files normalized is IMHO the best experience, yes, I have symlinked, but if I need to setup a new mac (that does not happen often) then I could forgot about it and will take an extra step to setup, as I said that's just my preference.

Also I want to say that the ~/Library/Application Support directory only works good for desktop app, so it's easy to get rid of the configurations of an app that you want to uninstall (I use AppCleaner), but terminal apps you install most likely by a curl|bash or brew, so there's no point on using that directory IMHO, to me feels that the maintainers are not mac users so they don't care on improving that, for me, is a pain point.

But that does not take the merit of nushell, from all the other new ones (fish, oil, etc) I think is the one that I enjoyed the most.

samatman

iterm2 puts config in ~/.config, while also having a directory in ~/Library/Application\ Support/ (habit). The author of iTerm has more credibility than the person you're replying to imho.

If a program is putting text files a user is supposed to edit in that directory, that's a mistake. If the application doesn't live in ~/Applications and provide a GUI for editing configuration, the file belongs in ~/.config and the app should follow XDG standards in general.

130e13a

surely something as basic as the location of the config folder can somehow be changed to a custom path, right?

johnmaguire

Configuring where configuration data lives can be tricky. (Chicken/egg problem.)

But you can certainly create your own symlink.

norman784

Yeah, the issue is mainly if you setup a new machine with your dot files, you need to remember to setup the symlink, because you don't do that so often is so easy to forgot. Also I pointed that out because I share my dot files between Mac and Linux and that's certainly annoying to have two paths for both.

DeathArrow

>This is just an example from YAML to JSON, but you can convert much more formats into other formats.

>open dev/home-impermanence/tests/impermanence.yml | to json

I can do it with PowerShell:

$os_list = (Get-Content -Path "C:\temp\operating-systems.yml" | ConvertFrom-Yaml)

Set-Content -Path "C:\temp\PowerShell_operating-systems.json" -Value ($os_list | ConvertTo-Json)

Semaphor

That is a great example, but for different reasons. I think PowerShell is amazing, but it never feels like something I want to work in as a shell. Writing scripts in an IDE, sure. But to convert some yaml to json I’d much rather type open/file.yml | to json

0x445442

This is where I’m at with PS as well. It’s stuck in this no man’s land between bash and python. It’s a better scripting language than bash and a better shell than python. But when compared to their main purposes it’s a worse shell than bash and a worse scripting language than python.

The caveat of course is Windows system administration. I’m sure it’s excellent in that domain.

Semaphor

I end up using C# as a scripting language, the GUI on Windows, and ZSH on Linux Servers…

vips7L

OP here wrote this the most verbose way I could think possible. Most commands are pre-aliased in PowerShell and arguments are fuzzy matched as long as they're not ambiguous.

For example:

   Remove-Item $directory -Recurse -Force
   rm $directory -r -fo

For this specific example ConvertFrom-Yaml actually doesn't exist as a standard cmdlet and ConvertTo-Json isn't aliased by default:

    gc ./something.yml | ConvertFrom-Yaml | ConvertTo-Json > /some/file.json

undefined

[deleted]

js2

With any shell:

    $ brew install yq
    $ yq -o json . < config.yml

ratboy666

This... yq eats yaml. And this is all I need to know (really). I don't know yaml. I don't WANT to know yaml.

Two letter command which I can remember, in the same way that I know jq. And, as a short-form jo. I would not use jo to eat json. I do think that yq is "misnamed" slightly, in that there is no yo command.

(note that I do have yq installed, but not nushell or PowerShell).

shell is glue, not oop -- json is an object notation, converted to stringyness. Which makes for oop->shell. Since "objects" are programmer-think, this should not be the primary command interface. People (not programmers) recognize this, and thus PowerShell is not used by "non-programmers". Ok, you want something above bash (sh, shell), for more programming structure? This is why the #! construct is exec() is so important. That lets you use... um awk, sh, (and should support PowerShell -- not sure). Even C (with tiny-c). I would go with javascript, myself, because it fits with json, and thus jq and jo in the eco-system.

Now, for a criticism of yq -- jq is 30K for a front-end and 350K (or so) for a library. jo is 120K, yq is (gulp) 12MB. Ok, I have the disk space. And it is GO, so ok. Compared with the other GO programs I use commonly: minio (100MB), mcli (mc, 20MB), doctl (20MB), it isn't bad at all. But, I guess that is what GO demands...

Can I teach "functional shell"? Frankly, no. I can get through simple shell in a semester.

ravi-delia

I mean, yeah? As much as I hate to admit it (and believe me, I hate to admit it), PowerShell is better than bash at composing tools made by all sorts of people on the fly in easy to write pipelines. I have my issues with it as a language, but it's not like I'm thrilled to write bash. Nushell is an attempt at making a scripting language which builds on bash, rather than supplanting it. PowerShell is much less nice on Linux, especially when you'd have to translate every existing resource.

sedatk

Yeah, PowerShell eliminated the output parsing overhead which was the significant portion of any composed shell operation. That's where all shells need to be heading I believe.

vips7L

Probably better to write this with the standard alias's so people don't complain about verbosity:

  gc ./something.yml | ConvertFrom-Yaml | ConvertTo-Json > /some/file.json
Also I don't think ConvertFrom-Yaml actually exists as a standard cmdlet.

ac130kz

Powershell is also quite anti-semantic, non-portable and verbose

delta_p_delta_x

> anti-semantic

Why?

> non-portable

PowerShell 6 and later run on Windows, macOS, and Linux.

> verbose

This is by design.

ac130kz

>Why?

Case insensitive, weird parameter passing, no Posix-like interface.

>Windows, macOS, and Linux

Yet it is still mostly suitable for Windows, where it makes sense with weird (read: mostly bad and outdated) platform-wide proprietary decisions.

>This is by design

Well, humans should not spend too much focus on verbosity, maybe I'm wrong, at least that's what I've learnt from a university HCI course.

rprospero

> > anti-semantic > Why? I can't speak to the other poster, but I found the PowerShell example to misleading because it required the presence of a variable that the Nushell did not. I had to read through the code three times to understand:

- Whether the code was modifying some fundamental environment variable that would affect the running of other programs? - If the variable would need to be accessed after the command was run? - Why the variable was named `os_list`? This was admittedly stupidity on my part, but it wasn't event a concern with Nushell.

> > non-portable > PowerShell 6 and later run on Windows, macOS, and Linux.

PowerShell is absolutely multi-platform and that should never be held against it. However, my personal experience has been that most PowerShell guides assume that you are running Windows and will attempt to call commands not available on other platforms (e.g. OS services, other applications). Granted, scripting tutorials for Linux and OSX also assume the presence of certain services, though it's easier to search my path for `7z` than figure out whether the Get-Acme-Version command is available. Nonetheless, the issue is more of documentation than implementation.

> > verbose > This is by design

As for the verbosity, I'll fully agree that PowerShell is highly verbose by design. However, that's a design decision that makes it inappropriate for some applications. An aircraft carrier is larger than a kayak "by design", but that doesn't make it any easier to strap to the top of your car.

stoplying1

Lol so what happens if I run 'curl' in my PS6 script? Asking for a friend with PTSD.

majkinetor

Its not verbose. Its just that people that use it like to share verbose stuff as it is more helpful to others.

_dhruva

I thought the original Nushell was written by Jonathan Turner.

Is this different? Some attribution in the article would help.

(Thanks for pointing, there are links to original in the article)

https://www.nushell.sh/

wodenokoto

> I packaged it for OpenBSD, so it's available on -current (and will be in releases after 7.3 is out), the port could be used on 7.2 with no effort.

I think this is what makes it sound like the author of the article is the author of nushell. My first reading led me to believe the same, but she is "only" responsible for the OpenBSD package.

solene

oh, I'm indeed not the author of nushell, I'll try to make it more clear!

afranchuk

It doesn't seem so. While not immediately clear, this article doesn't seem to be claiming ownership of the project. It is a third-party review/introduction. They link to the project after the first section.

jamincan

I get the impression that she packaged it for OpenBSD and wrote this as an intro to the shell for others. The 'written by Solene' bit reads initially as though she's claiming to have written Nushell, but when reading the text, it's pretty clear she didn't:

> With nushell, it feels like I finally have a better tool to create more reliable, robust, portable and faster command pipelines. The learning curve didn't feel too hard, but maybe it's because I'm already used to functional programming.

asicsp

Previous discussions about Nushell (https://hn.algolia.com/?q=Nushell), for example:

https://news.ycombinator.com/item?id=27525031 (763 points | 1 year ago | 398 comments)

https://news.ycombinator.com/item?id=20783006 (1477 points | 3 years ago | 366 comments)

dang

Thanks! Macroexpanded:

Nushell 0.60 Released - https://news.ycombinator.com/item?id=30772042 - March 2022 (40 comments)

Nushell: A New Kind of Shell - https://news.ycombinator.com/item?id=30718349 - March 2022 (8 comments)

Nushell – a new type of shell written in Rust - https://news.ycombinator.com/item?id=28968966 - Oct 2021 (3 comments)

Nushell 0.38 - https://news.ycombinator.com/item?id=28841901 - Oct 2021 (1 comment)

GitHub – nushell/nushell: A new type of shell - https://news.ycombinator.com/item?id=27525031 - June 2021 (398 comments)

Nushell: A New Type of Shell - https://news.ycombinator.com/item?id=26712741 - April 2021 (2 comments)

Cbsh – a couchbase shell in rust on top of nushell - https://news.ycombinator.com/item?id=24767244 - Oct 2020 (4 comments)

One Year of Nushell - https://news.ycombinator.com/item?id=24259914 - Aug 2020 (47 comments)

Nushell – A New Type of Shell - https://news.ycombinator.com/item?id=22880320 - April 2020 (37 comments)

Nushell – a modern shell written in Rust - https://news.ycombinator.com/item?id=20845584 - Aug 2019 (4 comments)

Introducing nushell - https://news.ycombinator.com/item?id=20783006 - Aug 2019 (366 comments)

Daily Digest email

Get the top HN stories in your inbox every day.