xonshとは
Pythonでできたシェル。でもってPythonで書ける。linuxのコマンドとも混在可。
シェルスクリプト??なにそれおいしいのというPythonエンジニアにおすすめ
環境
$ cat /etc/lsb-release
DISTRIB_ID=elementary
DISTRIB_RELEASE=5.0
DISTRIB_CODENAME=juno
DISTRIB_DESCRIPTION="elementary OS 5.0 Juno"
install
pipでもaptでもインストールできます
$ sudo pip install xonsh
(python2と3が混在している場合pip3かな?)
or
$ sudo apt install xonsh
で、注意
aptでインストールすると、古いバージョンがインストールされます。
最新版は今0.8.4ですが、多分0.6.0とかが入ると思います。
アプデでPythonの機能が使えるようになってたりいろいろあるので、最新の安定版を使うのが望ましいかなと思います。
じゃあpipしよう。
でpipしたら/usr/local/bin/xonsh
にインストールされます。
これでログインシェルを変更しようとすると
$ chsh
パスワード:
tia のログインシェルを変更中
新しい値を入力してください。標準設定値を使うならリターンを押してください
ログインシェル [/bin/bash]: /usr/local/bin/xonsh
chsh: /usr/local/bin/xonsh はシェルに指定できません
とか言って来やがります。
というわけでxonshをシェルと認めさせるためには/etc/shells
に追記します
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
# 追記
/usr/local/bin/xonsh
これで$ chsh
でいけるはず
設定ファイルいじるのコワイって人は、aptしたあとにpipすると、2つ(/usr/bin/xonsh
, /usr/local/bin/xonsh
)インストールされちゃいますが、なぜかusr/bin/xonsh
の方(aptではいるやつ)のxonshのバージョンも最新になってます。これでchsh -s /usr/bin/xonsh
でいけるはず
使ってみよう
$ echo hoge
hoge
$ ls
Documents Music Public Templates Downloads Pictures Videos
$ pwd
/home/tia
という感じに、いつものコマンドはいつものように使えます。
で、Pythonが書けるとどういうことか。
$ print('hoge')
hoge
$ import os
$ os.name
'posix'
$ for i in range(5):
. print(i)
.
0
1
2
3
4
という感じになります。
いつものシェルとして動作するのをsubprocessモード、pythonとして動作するのをpythonモードとか言います。
で、なにが嬉しいかというとpythonのstrとsubprocessの文字列の相互運用ができること
python str から subproess string
$ echo @(2 ** 10)
1024
subprocess から python
$ print($(ls))
Documents
Music
Public
Templates
Downloads
Pictures
Videos
はい。
まあ実際いれて触ってみてもらえば早いと思います。
$()
でsubproccess string からpython str または subproccess string
$ echo $(3 * 4)
12
$ echo $(ls)
Documents
Music
Public
Templates
Downloads
Pictures
Videos
$[]
でsubprocessを実行、結果を表示、返り値はNone
$ a = $[echo a]
a
$ a
$ a is None
True
!()
でsubprocessのclassが返ってくる
$ p = !(pwd)
$ p
CommandPipeline(stdin=<_io.BytesIO object at 0x7f8d126014c0>, stdout=<_io.BytesIO object at 0x7f8d126010a0>, stderr=<_io.BytesIO object at 0x7f8d12601360>, pid=5776, returncode=0, args=['pwd'], alias=None, stdin_redirect=['<stdin>', 'r'], stdout_redirect=[4, 'wb'], stderr_redirect=[12, 'w'], timestamps=[1544454131.2289853, 1544454132.1424832], executed_cmd=['/bin/pwd'], input=, output=/home/tia
, errors=None)
$ p.output
'home/tia\n'
![]
でsubprocessを実行、結果を表示、classが返ってくる(HiddenCommandPipelineってやつ)
$ p = ![pwd]
/home/tia
$ p
$ type(p)
xonsh.proc.HiddenCommandPipeline
$ p.returncode
0
@()
でpythonからsubprocess
リストを指定すると順番に実行してくれる
import xonsh
$ echo @(xonsh.__version__)
0.8.3
$ l = [1,2,3,4,5]
$ touch @(l)
$ ls
1 2 3 4 5 (省略)
for文とかの中にも全然書ける
$ for i in range(1,5):
. touch @(i)
.
$ ls
1 2 3 4 5 (省略)
コマンドを書く
コマンドもPythonで書ける
def _my_echo(args, stdin=None):
print(' '.join(args))
$ aliases['my_echo'] = _my_echo
関数を書いて、エイリアスを貼るとコマンドとして使えるようになる。
関数名とエイリアス名を被せないように注意
引数は、ひだりから
args: 引数がリストに入ってる
stdin :
stdout:
stderr: 名前の通りのファイルオブジェクトが流れてくる
あとまだあるらしいけど、この辺から先は自分がまだ把握できてないので、ptk(ぷろんぷとつーるきっと)とかって調べると幸せになれると思う。
これで例えば(僕が使ってる)ターミナルからgoogle翻訳に飛べるやつ
デフォルトで英語から日本語
-jオプションで日本語から英語
manコマンドの結果をそのまま流して見るとかもできる
def _trans(args, stdin=None):
from urllib.parse import quote
from time import sleep
options = [(index, value) for index, value in enumerate(args) if value[0] == '-']
options.reverse()
for i, v in options:
del args[i]
if '-j' in [v for _, v in options]:
url = 'https://translate.google.com/?hl=ja&tl=en&text='
else:
url = 'https://translate.google.com/?hl=ja&tl=ja&text='
if stdin is None:
if not args:
print('trans {arg[0]}')
print('_trans(args)')
return 1
for w in args:
text = quote(w)
chromium-browser @(url+text)
sleep(1)
else:
while True:
text = quote(stdin.read(5000))
if text == '':
break
chromium-browser @(url+text)
sleep(1)
まとめて
基本はいつものPythonとLinuxのコマンドです。
あとは、僕自身まだxonshをxonshらしく使いこなせてはいないので、精進します・・・という感じですが・・・
Python大好き他の言語なんてよほどのこと(モバイル開発とか)がないと使いたくない、みたいな人にはとてもおすすめです。なぜなら僕がそうだから