The Xonsh Python Shell
xon.sh
xon.sh
Ref: See "TAGLINES" def in https://xon.sh/_modules/xonsh/xonfig.html
Source: my 1st cousin, one of its co-creators and core maintainers.
I've been using it as my default shell for the past 2 years, and now I pretty much can't work without it.
Thank you, thank you, thank you!
xonsh being pronounced /kɑnʃ/ and not /eks.ɑnʃ/ or /xɑnʃ/, or even /zɑnʃ/, is just one of those things I have to remember.
pronouncing TeX /tɛk/ is better than /tɛks/, but really it's /tɛx/, the way Bach is /bax/.
from pathlib import Path
from xonsh.events import events
class CwdPath(type(Path())):
def __iter__(self):
return self.iterdir()
$cwd = CwdPath.cwd()
@events.on_chdir
def set_cwd(olddir, newdir, **kw):
$cwd = CwdPath(newdir)
It's really nice being to do for f in $cwd:
echo @(f.name)
or equivalent, especially with python's glob syntax for f in $cwd.glob("**/*.png"):
#Do a thing
Overall I've been really enjoying xonsh, now that I've got the hand of it.Mostly I'm just sticking with bash, not because it's best, but because it's available everywhere. I don't really feel setting up something like Xonsh, zsh or ksh on every server I ssh into, to much work. The time is honestly better invested in getting better at bash, if you spend your day on multiple different systems. It's a little sad actually.
ls -fr \
| select (f: f.suffix in ('.c', '.h')) \
| map (f: f.read().count('\n')) \
| red +
- List only files (-f) recursively (-r).- Select those whose suffix is .c or .h.
- Map qualifying files to the count of \n in the file.
- Reduce those counts to a total using +.
The parentheses delimit Python functions (marcel permits omission of "lambda").
That's unfortunate, because as awful as bash may be, a shell that works natively on all three systems would be far more valuable. Python has all that platform abstraction already built-in.
judging by the nickname and github url it's yours https://github.com/geophile/marcel
If a xonsh user does want to do strict separation, how does that work? Syntactically, how do you separate shell code from Python code?
I'd love to use this on Windows but have been running into issues. I'm like 99% sure it's because of my own dumb (unrelated) config issues, but I still can't use xonsh because of it.
Having people to ask questions of would be awesome!
Simple bash scripts can easily grow into tangled behemoths and there's not an easy, incremental rewrite step (like JS → TS) that would add a lot of structure. Jumping straight to Python is usually painful because of all the subprocess calls.
It seems that xonsh could bridge that gap, but I'm not sure how many people use it for that purpose, or if people use something else (e.g. Oil shell).
ls -fr \
| select (f: f.suffix in ('.c', '.h')) \
| map (f: f.read().count('\n')) \
| red +
In Python, it would be: from marcel.api import *
print(first(ls(file=True, recursive=True) |
select(lambda f: f.suffix in ('.c', '.h')) |
map(lambda f: f.read().count('\n')) |
red('+')))
You can see that the ls, select, map, and red commands are called directory from the Python code, without having to call Popen, os.system(), etc. Each version of the code (shell, script) runs in one Python process, (not one process per command).I've written simple small scripts with it for my last two jobs.
And you can use matplotlib, numpy, and cv2 directly from the terminal. Freaking awesome.
The only major issue I'm encountering is that if the prompt is wider than the terminal (due to your path + git branch name being too long) it goes bezerk.
You're likely using prompttoolkit for the prompt. If this is a problem for you, you can set it to use readline, and it will behave the way most shells do.
(I reposted because I found out about it recently)
If the initial “X” isn’t alienating enough, stay for the “nsh” consonant cluster at the end!
It's simply initially off-putting.