Nsh: A fish/bash-like Posix shell in Rust
github.com
github.com
While I personally think shells that abandon POSIX/bash compliance are much more interesting as those can implement a sane scripting language, sticking with bash but improving interactivity is probably going to make more users happy as bash is so ubiquitous.
Is it really? Projects like ble.sh [1] seem to pull off advanced features like syntax highlighting and enhanced completion with pure bash without the need for reimplementing a whole shell from the ground up.
I like zsh because it is mostly (entirely?) POSIX compliant, but adds extended features. I think that's the best approach to make it easier for people to start using your shell.
random note: back when the Go language was first released I wanted to try it out.. I started making a shell that I called GoSH. Didn't get very far, you could execute programs, change directories etc. It was fun! And taught me a lot about low level languages.
For anyone after an upgrade path from Bash/Zsh then Oil shell is a lot more mature: https://www.oilshell.org/
What does this really mean? Especially the ergonomic part?
For example, replacing "&&" and "||" with "and" and "or", is not an improvement. There are many other such changes that make the shell more verbose without bringing any advantage.
This also happened with the C shell, csh, which introduced some convenient new features for interactive use, but it also included a large number of gratuitous changes in the syntax that were not improvements.
> For example, replacing "&&" and "||" with "and" and "or", is not an improvement. There are many other such changes that make the shell more verbose without bringing any advantage.
In Fish, `and` was never a synonym for `&&`, and `or` was never a synonym for `||`. Fish's use of `and` and `or` also did not introduce any syntax that you won't find in Bash and friends. `and` and `or` in Fish are _commands_, and they use the _pre-existing syntax_ for _normal commands_.
This is absolutely an improvement, because it's strictly less syntax that allows you to do all of the same things with virtually no increase in the number of characters. `; or` is only a single character more than ` ||`, and `;or` is the same number of characters as ` ||`. This is a very bad example of ‘increased verbosity’.
If you like this syntax, that is fine, but I do not like it, and I also find it illogical, because McCarthy "and" and McCarthy "or" are really alternatives to the sequential execution denoted by ";", not something that is done after a sequencing delimiter, so this and many other details like this have prevented me to switch to using fish, even if fish also has many other features that I like.
Also, I have never reached deep enough in the fish documentation to discover how you can write the equivalent of:
cmd1 && cmd2 || cmd3 && cmd4 &
from traditional shells, when "and" and "or' are ordinary commands. I assume that you might need to use parentheses before "&".The fact that not only the symbols have been substituted but they have also been made ordinary commands is a serious regression. Less syntax that removes your ability to write something is not an improvement.
For any shell wannabe, there is a very large part of the syntax used by ksh/zsh/bash that can be changed without problems, e.g. conditional structures, loops, variable and function definitions, various kinds of parameter expansions and expressions and so on.
None of those is specific for a shell language and it is likely that better replacements can be found.
On the other hand, for the syntax of a shell command list, which uses expansions, redirections and "|", "&&", "||", ";", "&", nobody has found yet a better alternative so any shell should better keep it unchanged.
‘alternative’ is doing some interesting work here, as evidenced by the example you use in the text that follows. If `&&` and `||` themselves sequencing delimiters that additionally imposed conditions upon the exit statuses of the commands in the sequence while also re-emitting those statuses, `&&` and `||` wouldn't behave the way they do in your example, affecting the behavior of the `&` operator. This means that your example shows that `||` and `&&` are also in a distinct syntactic category from that of `;`. Alternatively, we can nominally put them in the same category, as Bash does by calling `;`, `||`, and `&&` ‘control operators’ (along with pipes and other things), but then we find ourselves in a situation where _some_ control operators modify the scope of any `&` operators that succeed them but other control operators don't. So how conceptually useful is this category, now?
> Also, I have never reached deep enough in the fish documentation to discover how you can write the equivalent of: > > cmd1 && cmd2 || cmd3 && cmd4 & >
I am glad this expression is not idiomatic Fish. `&&` and `||`, as command operators here, serve to give chaining some commands together some resemblance to boolean expressions in other programming languages. But would-be formula in first-order logic which captures the logical component of this expression
a ∧ b ∨ c ∧ d
is not a well-formed formula! So what it means is a matter of convention. The role of the final `&` here is the same: yet another construct whose meaning depends on the script language author's choice of operator precedence.By contrast, in Fish, the behavior you should expect falls out of the ordinary syntax for the commands and the manual's description of the builtin `and` and `or` commands. In Fish, this is also quite easy to look up, e.g., with `help and`, which yields:
> and is used to execute a command if the previous command was successful (returned a status of 0).
> and statements may be used as part of the condition in an while or if block.
> and does not change the current exit status itself, but the command it runs most likely will. The exit status of the last foreground command to exit can always be accessed using the $status variable.
which is all you need to understand how `and` works. By contrast, in Bash (which I'll continue to use as my example for the more conventional syntax and semantics), to figure out your example expression, you have to read this from the Bash docs (after reading the section on pipelines, of course):
> Lists > A list is a sequence of one or more pipelines separated by one of the operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or <newline>. > > Of these list operators, && and || have equal precedence, followed by ; and &, which have equal precedence. > > A sequence of one or more newlines may appear in a list instead of a semicolon to delimit commands. > > If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0. These are referred to as asynchronous commands. Commands separated by a ; are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. > > AND and OR lists are sequences of one or more pipelines separated by the && and || control operators, respectively. AND and OR lists are executed with left associativity. An AND list has the form > > command1 && command2
> command2 is executed if, and only if, command1 returns an exit status of zero (success). > > An OR list has the form > > command1 || command2 > > command2 is executed if, and only if, command1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list.
Okay, okay. So anything conjoined by `&&` and `||` is like one big command, since && and || have higher precedence than anything else. That's why the final `&` in your example applies to the whole list of pipelines that come before it.
Only that's not true! A look inside the manpage for bash's builtins reveals blurbs like this in the entries for `set` and `trap`:
> part of any command executed in a && or || list except the command following the final && or || > part of a command executed in a && or || list except the command following the final && or ||
which is the exact opposite of the behavior `&&` and `||` exhibit in your example when followed by `&`. Fantastic. Very ‘logical’.
To return to this:
> Also, I have never reached deep enough in the fish documentation to discover how you can write the equivalent of: > > cmd1 && cmd2 || cmd3 && cmd4 & >
Fish has blocks, so you'd write:
begin
cmd1
and cmd2
or cmd3
and cmd4
end &
or use a function. But the above example doesn't actually work, because unfortunately Fish has a deeper defect than a syntactical discrepancy here, and job control is not implemented for Fish functions, see https://github.com/fish-shell/fish-shell/issues/238 and the Fish manual's section on job control https://fishshell.com/docs/current/language.html?job-control.... But again, this is not a syntax issue but a job control issue, a defect in the implementation rather than the design of the syntax.Finally:
> For any shell wannabe, there is a very large part of the syntax used by ksh/zsh/bash that can be changed without problems, e.g. conditional structures, loops, variable and function definitions, various kinds of parameter expansions and expressions and so on. > > None of those is specific for a shell language and it is likely that better replacements can be found.
This is actually interesting and constructive, because it gives a clearer picture of the kind of ‘improved’ shell you might want. I hope that one comes to be, if it's not already being worked on.
But I just disagree that the traditional command list structure is necessary or good. It's full of arbitrary conventions and gotchas, and the additional flexibility it gives you is trivial. It's a bummer that Fish's job control lets us down here, but that has nothing to do with the syntax.
I applaud this project for bringing fish goodness to more people, although I don’t quite get why people cannot just learn fish. Fish is very simple. There is not that much to learn.
Maybe it matters if your write a lot of shell scripts but for anything complicated I use Julia, Python, Go or some other more proper language.
To me shells are mainly for interactive work and really simple scripts without control flow, beyond perhaps a for loop.
womp womp
The experience out of the box (coupled with something like starship) is pretty good but I don't like the incompatibility with basic things, like $() vs ().
I also find fish to be a bit on the slow side in some instances, so I think I'll keep tabs on nsh
Configuration isn't for you. It's for other people. Configuration is the part of a program that performs the function of making it useful for more than one person. It is the necessary glue that brings together many developers and many users into one project.
Just to state the obvious examples, i18n is exposed through configuration, accessibility features are configurations. These aren't optional parts of a program that can simply be designed around.
To be clear, I agree with you that human preferences are valid as such, just clarifying that your parent comment is profoundly wrong even if you think that all people ought to have the same preferences.
I’m fact why even have Linux or macOS running atop x86 when we have perfectly good z80 micro computers running a BASIC interpreter…
I’m all for difference of opinions but that is clearly the dumbest one posted to HN in a long time.
There’s no such thing as a one size fits all. To suggest there is only demonstrates how little exposure you’ve have to the wider field of computing.
Choice arises because humans are different, and want - and need! - different things.
(fish)$ bash
(fish>bash)$ source ./random.sh
(fish>bash)$ fish
(fish>bash>fish)$ (fish)$ bash -c ./random.sh (fish)$ bash random.shI mainly use fish for interactive work not for programming. Then I use a real programming language.
If features are integrated, then I would probably want to have something about error handling because it is difficult to get right in bash even with shellcheck¹ plus shellharden², and gets just worse when things run in parallel.
http://nuttx.incubator.apache.org/docs/latest/applications/n...