William Droz -- blog

Having fun with cutting-edge technologies


Xonsh – A modern shell that enable python in your terminal

Xonsh – A modern shell that enable python in your terminal

Maybe once a month/year you have to write a bash script. Certainly less trivial of this one

#! /bin/bash
if [$1 == "hello"]
    then
        echo "hello $USER"
fi

It’s just answer hello back to the user. Let’s try to run it

[email protected]:~/tests_sanbox$ bash script.sh hello
script.sh: line 2: [hello: command not found

Argh, doesn’t work ! Why ? Because I forgot to put spaces after ‘[‘ and before ‘]’… what year is it ? 1999 ?

Let’s try xonsh !

First step with xonsh

sudo pip3 install –upgrade xonsh

now you can use xonsh. But before playing with it, I recommend to run the wizard.

xonsh
xondif wizard

Answer the wizard according to your needs. Now let’s make some commands

[email protected] ~/tests_sanbox $ for i in range(10):
................................     echo @(i) > @('file_{}.txt'.format(i))
................................     
................................ 
[email protected] ~/tests_sanbox $ cat *.txt
0
1
2
3
4
5http://xon.sh/tutorial.html
6
7
8
9
[email protected] ~/tests_sanbox $ ls *.txt
file_0.txt  file_1.txt  file_2.txt  file_3.txt  file_4.txt  file_5.txt  file_6.txt  file_7.txt  file_8.txt  file_9.txt
[email protected] ~/tests_sanbox $

Yes, I just created 10 files, with index both in name and inside the file. Yes, I just combined both python and bash in the same snippet.

If you want a better preview, you can look at the official tutorial : http://xon.sh/tutorial.html

Want a more customized prompt ? Challenge accepted

Let’s make more stuff in the prompt! Why not the current time and the latest story from Hacker News ?

Results prompt



How ? Just edit ~/.xonshrc and put this

from bs4 import BeautifulSoup
import requests
import datetime
import time
from threading import Thread
LATEST_NEWS = ''
$XONSH_SHOW_TRACEBACK = True

DEFAULT_PROMPT = '{BOLD_GREEN}{user}@{hostname} {BOLD_RED}%s{BOLD_CYAN}{cwd}{BOLD_CYAN} {prompt_end}{NO_COLOR}'

def ask_hn():
    global LATEST_NEWS
    while(True):
        hn = requests.get('https://news.ycombinator.com/').content
        soup = BeautifulSoup(hn, 'html.parser')
        last_story = soup.find_all("a", "storylink")[0].contents[0]
        LATEST_NEWS = last_story
        time.sleep(10)

Thread(target=ask_hn).start()

def update_prompt():
    return ('>>> {BOLD_YELLOW}%s{NO_COLOR} <<<\n' % LATEST_NEWS) + DEFAULT_PROMPT % datetime.datetime.now().strftime(" [%H:%M:%S] ")

$PROMPT = update_prompt

Remember to exit and type xonsh again.

Basically, you have to put in $PROMPT a function that create the prompt. This function will be called EACH TIME you type something in your shell. That why I create a thread that cache the latest news for 10 sec.

I know, it’s a little bit overkill, but it’s works !

Final step, put xonsh as your default shell

check where is your xonsh

which xonsh

Add it to the shells list

sudo vim /etc/shells

Finally we can change the default shell (need logout and login for take effect)

chsh -s $(which xonsh)

I hope you had appreciate this little introduction to xonsh. But by careful if you want to use it in production! I only shown the good parts ! There are things your should check, like setup environment variables.


comments powered by Disqus
About
I’ve been programming since 2004 and I got my master degree in software engineering in 2015. I worked as a research assistant at “He-arc Ingénierie” until 2018. I'm now working as a Research and Development Engineer at Idiap. With my work, I have the opportunity to play with some cutting edge technologies, like Tensorflow, Keras and Spark.