Xonsh, a Python-ish, Bash-compatible shell language and command prompt
xonsh.org
xonsh.org
xonsh looks very cool. Shell scripting languages are famously obtuse and underpowered, and we've thought about how to cleanly merge shell scripting with a real language. It's heartening to see an attempt at it.
Ambiguous syntax is a sticking point. For example, say the user runs this:
[ 1 ]
is this constructing a Python list with the value 1, or is it invoking /bin/[ with two arguments? It's ambiguous! It looks like xonsh interprets it the first way. Any thoughts on this issue?A related issue is the relationship between bash functions and Python functions. I'd be very interested to see how xonsh approaches this.
Also, here's some unsolicited advise, from one non-POSIX shell maintainer to another: The claim that xonsh is "bash-compatible" is delicate. Full bash compatibility requires your shell to be insane. E.g.
echo foo | cd /
cd / | echo foo
In bash, only the second line will change your working directory. Or consider this command: *
this finds the first (for some meaning of first) file in your directory and invokes it with all other files as arguments. I tried it: xonsh doesn't handle either of these "correctly," which is to say that xonsh isn't yet insane. That's good news! On the other hand, this means it's not really bash compatible.IME nobody really cares about full bash compatibility. What they want is for their existing bash stuff to just work. Bash shebang scripts will just run in real bash, but that leaves shell-integration scripts: virtualenv, rbenv, etc. Supporting that stuff is one of the most common requests that the fish shell gets, and one of the most commonly cited reasons for not using fish.
Here's a piece of rbenv's bash integration: https://github.com/sstephenson/rbenv/blob/master/libexec/rbe... . It's short but there's a lot of features being used: set, shopt, IFS, functions, etc. If you're aiming for bash compatibility, that's your target!
In the meantime, I suggest changing the language to express that xonsh is bash-like, not bash-compatible. Otherwise users are going to be confused and disappointed.
I'd like to point out though, that the goal is not to have bash-compatibility. As you point out, bash does some insane things and that is exactly what I want to avoid with xonsh. I should be able to give xonsh to a programming newbie and they should not experience any gotchas once they know the language.
I have been pretty careful to say BASHwards-compatibility in the docs and elsewhere, for exactly the reasons you mention. The goal isn't to be bash with some python-isms, but to be python with the useful parts of the shell syntax. Like any good technology, it should interface as well as it can (ie when not insane to do so) with the previous technologies. For example, read in the bashrc or take advantage of the bash completion functionality. That is what BASHwards was meant to mean. @ngoldbaum seems to have submitted the link here, under 'bash-compatibility.' Oh well. This probably is proof enough that I should change the 'BASHwards' language elsewhere. Thanks for the tip.
Keep doing great things with fish!
It seems to be more intended to be not backward-compatible, but to have some attention to minimizing the pain of transition, which is valuable, but needs different language to communicate.
echo foo | cd /
cd / | echo foo
In bash, only the second line will change your working
directory.
Um... in Bash, neither of those change your working directory (unless `shopt -s lastpipe` is set, in which case: the first does).shameless plug, but I made a utility to solve the problem: https://github.com/edc/bass
So you can write `bass source /usr/local/bin/virtualenvwrapper.sh ';' mkvirtualenv env1`, which of course can be shortened with a function.
It was called REPL (Interlisp-D, Lisp Machine, Cedar, Oberon), Workspace (Smalltalk), but then UNIX won.
I used tclsh for a while. IMO a shell language needs the "function arg1 arg2" function-application syntax to fit with the way programs are called. Fortunately that style seems to be getting more popular - Haskell does it and to a certain extent so does Scala.
Just installed on my personal Macbook. Will see how it goes.
#!/usr/bin/ipython
files = !ls
for f in files:
print(f)
That being said, it is a bit clunky to use since it's not a proper shell, so xonsh is definitely a very welcome improvement.[1]: http://ipython.org/ipython-doc/stable/interactive/shell.html
and those are not everywhere.
You can source it with `. venv/bin/activate.fish`
See https://github.com/tdenniston/bish for the repo and https://news.ycombinator.com/item?id=9166386 for some previous discussion.
The language is still brand new and under active development. It's not stable yet.
Also some of us are being paid to write bash scripts. I'm for example forced into bash because of AIX server. Learing bash is fun and profitable...
What? Consider yourself lucky. All of my AIX was ksh. If I wanted to be especially rebellious, I would use ksh93.
Example:
10:54:01 foo@bar:~/scripts/xonsh$ xonsh
foo@bar ~/scripts/xonsh $ # no time prefix> PROMPT: The prompt text, may be str or function which returns a str.
If you need non-built-in values in your prompt, just set PROMPT to a function, and call something like `date` within the function. Use `%` to format `date`’s output into a template string, and then pass that template string to `xonsh.environ.format_prompt` to get the final value to return from the function.
a = $(ls)
a # '1\n2\n3\n4\n'
b = `ls`
b # [] <-- What?!
Because of these little surprises I cannot really feel confident using it. $ ls='foo'
$ cat test.sh
#!/bin/bash
ls ~
$ print(ls)
foo
$ ./test.sh
bin C:\nppdf32Log\debuglog.txt foo initrd.img.old lost+found opt run sys var
boot dev home lib media proc sbin tmp vmlinuz
cdrom etc initrd.img lib64 mnt root srv usr vmlinuz.oldEven if this thing can execute unmodified bash scripts (can it?), it seems to me that would be missing the point, which is to avoid the horror of writing complex bash scripts. When I start writing something in bash, because of those few things it makes so easy (e.g. running subprocesses), I usually regret it as the script grows. If xonsh can make those things just as easy, every script can be written in the right language – which is of course Python :) – from the start.
curl -O https://raw.githubusercontent.com/pypa/pip/master/contrib/ge...
sudo python3.4 get-pip.py
sudo mv /usr/local/bin/pip /usr/local/bin/pip3 # optional, adjust line below if ommited
sudo pip3 install xonsh
------
then:
chsh -s /usr/local/bin/xonsh <yourusername>
EDIT: Just realized I forgot a step. You have to edit /etc/shells to add /usr/local/bin/xonsh to change your shell to it using chsh.
brew install python3 # will install python3 but not make it default
mkdir xonsh && cd xonsh
virtualenv -p /usr/local/bin/python3 venv
source venv/bin/activate
pip install xonsh
xonshHere (https://news.ycombinator.com/item?id=9166386) is the previous discussion from last week.
Sadly no support for python 2.7 so I'm out of possibility to even test this.
Swapping pipe components at runtime with pipe_controller:
http://jugad2.blogspot.in/2012/10/swapping-pipe-components-a...
That above post was the last in a series that I wrote over a period. The series describes both a) a small experimental tool I wrote, with examples of a few ways of using it, and b) some other Python-shell tool alternatives that I came across. pipe_controller was inspired by reading about and trying out some of those other tools.
The post above links recursively to all the other posts in the series, but for convenience, I'm pasting selected other links below:
Using PipeController to run a pipe incrementally:
http://jugad2.blogspot.in/2012/09/using-pipecontroller-to-ru...
Some ways of doing UNIX-style pipes in Python:
http://jugad2.blogspot.in/2011/09/some-ways-of-doing-unix-st...
Plumbum, UNIX shell-like library and tool in Python:
http://jugad2.blogspot.in/2012/08/plumbum-unix-shell-like-li...