Xonsh: Python-powered, cross-platform, Unix-gazing shell
xon.sh
xon.sh
* Nesting bash and python scripts makes performance terrible compared to using python's subprocess module directly. I have a xonsh script at [0], with an equivalent written in straight bash. The python scripts ends in less than a second, the xonsh script takes ages.
- As a sub-problem of the above: You can't ctrl+c while in a python function in xonsh. That stinks.
* $(program) returns a string that ends with a \n. In bash, when the program returns a single line, the \n gets stripped.* It sometimes has problems with certain interactive programs. My last experience with this was sudoedit starting neovim in xonsh caused neovim to crash. XonSH -> Neovim works. Bash -> Sudoedit -> neovim works. but Xonsh -> Sudoedit -> Neovim doesn't.
And that's just a small list of my biggest gripes that I keep running into. I really hope to see the project improve though! Despite all the bugs, it's still my favorite shell by a mile.
[0] https://gist.github.com/roblabla/d82c440908d08c8a232ac483e6b...
“Uh ok so I have this JSON file. When I pipe this to `jq` I forget: to pivot an array of objects to an object keyed by array[x].id is it like `to_entries` then chain it to `map`? Uhh let’s look at the docs...”
However in Python I can write that function at the speed of thought. It may be a couple more lines of code but I’m also 100% confident in the output.
Like I understand some people can legitimately program in bash [0]. But I just can’t bring myself to practice. Why would anyone inflict this language on themselves?
[0] https://github.com/docker-library/python/blob/master/update....
Bash has a lot of pitfalls, but once you learn how to deal with them, it can also be quite superb for some tasks. Piping the output of a complex set of loops into GNU parallel and watching your computer process stuff at blazing speed is a very nice experience. Doing the same in python would be many time more verbose.
Personally, I stopped using `jq` in favor of python oneliners, they a bit more verbose but also cross-compatible, works out of the box (not everyone has jq, but most of people have python (pre)installed on their machines) and it is easy to implement a oneliner, i.e.:
curl -X GET "https://httpbin.org/json" -H "Accept: application/json" | python -c 'import sys, json; print(json.load(sys.stdin)["slideshow"]["author"])'
Do xonsh helps you write a tar command without googling [0] or browsing a man?$ yes test | tee /tmp/xonsh.log
$ wc -l /tmp/xonsh.log
208076 /tmp/xonsh.log
bummer
ctrl+c does eventually work several seconds later (about 10x slower) which is still a deal breaker as it could be disastrous when you need to abort a mistyped command or for scripts that give you a few seconds to abort before it does something the destructive step...It's the reason './' is not in the default path as well (so you can't place an 'ls' in your home directory and have the admin run your command instead of the real ls).
In my opinion, such few-dependency, high-importance tools should linked statically.
It's .NET based and very, very different from the sh lineage, but I absolutely love its ability to use objects instead of strings as the underlying transmission medium between "processes". E.g. ls gives you file descriptors, ps gives you process descriptors, etc.
I know about the different concept of Powershell for quite a while now, but since it is MS tech I didn't expect it to be available for Linux. Maybe I will try someday how it feels, but I am sceptical as the thing I like most about POSIX shells is that everything is just text and I wonder how Powershell will integrate with other *nix tools.
That said, the way the language is designed makes calling into compiled .NET code seamless, which in turn makes doing really sophisticated shell scripting a breeze. When I saw what xonsh was trying to do, I recognized a lot of "PowerShell solves this problem a bit more gracefully".
can you say why? Python's stdlib handles a lot of cross-platforminess, Python is mostly easy to write, and is available as or more easily than a C compiler on many platforms.
If we’re talking about new code, why is this the case?
The funny thing about Portage is though that Python doesn't cause any performance issues as Portage/Emerge is slow by design. So while Paludis is written in C++, it isn't much faster, as it still has to interpret all those thousands of bash-style ebuilds/exheres.
This might sound as if I wouldn't like Gentoo/Exherbo et al. but in fact, my desktop PC is running Gentoo or Exherbo for the last 10 years at least. But it was exactly that experience which made me conclude that system tools like package managers, shells, etc. should be written in statically linked languages.
it's the shell I always wanted. And cross platform to boot.
Alias ls -l?
aliases['ls'] = "ls -l"
Oops no I don't want that any more:
del aliases['ls']
Add dir to path:
$PATH.append('/foo/bar')
Just the awesome python syntax sugar and readbility right in the
May I never right a bash script again.
Bash is not going away any time soon, for better or worse..
For me, it's easier to remember that aliases acts like a dictionary, so I can treat it like any other dictionary. With "unalias" I have to remember the command. As I rarely use unalias (a few times over a period of years), I typically have to search the web on how to remove an alias.
And if it really bothers you, I'm pretty sure it's trivial to define an unalias function in Xonsh that will act as you expect (without needing parentheses).
It's part of the beauty of Xonsh - many such commands you're used to can be brought into it by writing fairly simple Python code.
However, I struggled a little bit with
$ time ls
where the output of `time` is mangled in-between the output of `ls` - this may be related to STDOUT and STDERR buffering?
I think the way people handle shell, as in typing commands on a dumb shell, has not improved for decades and I don't know why. The only thing they help without explicitly asking is with autocompletion.
I'm really tempted to try xnosh again as my daily driver for a few weeks though. I like the idea of typing out arbitrary Python code without spawning up IPython.
The problems people seem to be stating about xonsh were similar to a lot of the early bugs with Fish, but those things tend to go away once more people start using the shell and reporting issues.
I hope we got a whole new generation of usable shells with xonsh, oil and fish.
Except the damned name. Come on guys, there are already enough crazily named things out there, you didn't have to be another one :(
I will say I prefer names that can be searched for on their own (e.g. with Go people typically search for "Go lang").
And as much as I love Void Linux, it's better named than all the xbps-* package manager commands.
:)
pen2l will be reassured to learn that the process supervisor is straightforwardly named. (-:
* http://jdebp.eu./Softwares/nosh/guide/service-manager.html
posh, I agree, with the other poster, is a fabulous name for something like this
Shell scripts are a maintenance nightmare - even when used for personal scripts. They should be avoided at all cost.
I agree, however, that classic shells are worse, because they lack many of the niceties expected in modern languages and have opaque, sensitive syntax.
fish shell has made me pretty happy. It's a great middle ground. It makes no pretense at POSIX compatibility. Truly a shell for the 90s.
There's definitely a good demand for a modern shell scripting language but fish is an existing solution that is saner than bash/zsh.
I don't use fish as a shell but for shell scripts only as it acted a bit weird on me, though it's possible I didn't search enough but zsh can cover pretty much all I want from fish with plugins.
There is a port of a few very useful plan 9 tools, including rc and the Acme editor, in https://9fans.github.io/plan9port/
You should know when to stop and reach for a different tool, but that point isn't before you use shell scripts at all.
POSIX shell is not really worse than bash or any of the other choices imo. For tasks to which it's not suited, bash et al probably isn't either, and you should just use Python.
If they want bigger adoption, dedicating a bunch of people who do nothing but port zsh and fish plugins would probably go a long way.
https://github.com/shahinism/xontrib-fzf-widgets
You can get a list of (known) xontribs here:
The motto started out as "BASHwards-compatible", but that was unsatisfactory because on one hand it sounds like nonsense, and on the other hand, it's not actually compatible with Bash. So that devolved over time into what we have now.
https://github.com/xonsh/xonsh/blame/ebd4e597a3cf063b124e5a5... https://github.com/xonsh/xonsh/blame/82cac3fff08b5cc26e421f1... https://github.com/xonsh/xonsh/blame/bd964ce552282334c881181...
>>> ls `a(a+|b+)a`
aaa aba abba
Regex filename matching triggered by backticks. I like that design choice!1. caching pypi installs between instances 2. using a real terminal emulator which means you'll get to use xon.sh (or any shell) in it's full glory
Still a nice surprise to see repl.it embedded in the wild.
Sadly it doesn't play well with all of my three thousand various vim plugins, so I still haven't been able to use it as my daily shell. Hopefully someday!
set shell=/path/to/bash
to your vimrc and see how you get along.So, Xonsh is superior in the manipulation of shell objects. I felt super at home changing the shell prompt and configuring/extending the default Xonsh functionality. This is all because it's literally a superset of Python.
Fish however, blows Xonsh out of the water when it comes to autocomplete and navigation. Xonsh's autocomplete / suggestions are very very weak in comparison to fish's. You feel bogged down when trying to navigate directories quickly with Xonsh. I wrote a small blog post about it here [0]
There was a piece of software I was trying to write that was meant to be Xonsh but with Fish's autocomplete [1], but really didn't succeed and have slightly abandoned it for the time being. But maybe I'll pick it back up soon.
[0] https://ezb.io/thoughts/programming/mollusk/mollusk_1.html
I work on fish, and one of the things that the upcoming fish 3.0 contains is a new `math` builtin (previously we shipped a function of that name that just wrapped `bc`).
So your math expressions here are interesting to me, because they work in math (with the caveat that `` is still the symbol for globbing, so it needs to be quoted or escaped):
$ math 0x113e8b3
18081971
$ math '719 * 114679'
82454201
Adding them to the core syntax carries backward-compatibility questions and also isn't really what fish is about.I do think something like a Python shell is the best solution (for me), however, simply because of the ease of use with modifying the current state of the shell (environment variables, etc).
[0] https://gist.github.com/wackywendell/919042f19ab6932447df
x=foo; x=${x%o}; echo $x # prints 'fo'
Supporting that is non-trivial in python. There's no quotes around the strings, '%' is kinda weird there, etc.Of course, in python you can just say:
x="foo"; x=x[0:2]
... but those are not compatible with each other. colon does different things in posix sh than python, and it would be quite complicated to reconcile it.I'll also point out the parent poster, when they wrote "sh-lang", meant "the superset of posix-sh that zsh/bash users expect", because at this point quite a few bash features are expected to work in most sh-like shells.
Naturally, both xonsh and sh (and all other shells pretty much) are turing complete and can execute programs, which makes them all equally capable.
Having equivalent capabilities does not mean things are compatible though. I recommend reading up on what a POSIX shell is, and then reading fish and xonsh's arguments why they're not POSIX compliant (spread through various locations)