TL;DR
MySQL :: MySQL Shell 8.0 :: 13.3 Customizing the Prompt の情報は圧倒的に足りない
mysql-shell/README.prompt at master · mysql/mysql-shell を読むと良さそう
だがそれを差っ引いてもよくわからなかったので、ステップバイステップで作っていく記録
取り敢えず、 mysqlsh
が最初に食おうとするプロンプト用のJSONファイルは ~/.mysqlsh/prompt.json
, それが無ければデフォルトというかビルトインのJSONファイルのパスを探して(termの色数とか勘案しつつ)開くっぽい。
$ strace -f mysqlsh 2>&1 | grep json
open("/home/yoku0825/.mysqlsh/options.json", O_RDONLY) = 3
[pid 10699] stat("/home/yoku0825/.mysqlsh/prompt.json", 0x7fffae727880) = -1 ENOENT (No such file or directory)
[pid 10699] open("/usr/share/mysqlsh/prompt/prompt_256.json", O_RDONLY) = 4
カスタマイズしたいので、とりあえず ~/.mysqlsh/prompt.json
を作ることにする。
$ touch /home/yoku0825/.mysqlsh/prompt.json
$ mysqlsh
Error loading prompt theme '/home/yoku0825/.mysqlsh/prompt.json': Can't parse ''
mysql-js>
JSONとしてパースできなさそうなファイルを作るとフォールバックする。
mysql-shell/prompt_nocolor.json at master · mysql/mysql-shell など参考にすると、おそらく最小のコンフィグは↓のような感じ。
$ cat ~/.mysqlsh/prompt.json
{
"prompt": { "text": "mysqlsh> " }
}
$ mysqlsh
mysqlsh>
OK, 固定文字列はこれで出せる。
mysql
コマンドでいう \h
や \u
みたいな シーケンス はREADMEに Supported variables are:
で書かれているやつで、 %
でくくられたやつ。
ざっと user@hostname [database]>
みたいなやつにするにはこうかな。
$ cat ~/.mysqlsh/prompt.json
{
"prompt": { "text": "%user%@%host% [%schema%]> " }
}
$ mysqlsh
@ []>
接続してないから軒並み空っぽになってしまった。。
ちゃんと mysqld
に接続すれば出る。
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@localhost [d1]>
root@localhost [d1]> \use mysql
Default schema set to `mysql`.
root@localhost [mysql]>
OK。
ところでこの %host%
は飽くまでも mysqlsh
から見て指定した接続先ホストで、localhostになっている(これは mysql
の \h
も同じ)
俺はこれが嫌いで、 mysql
コマンドでも「クライアントから見た先じゃなくてサーバーサイドから取得したホスト名を表示したい」みたいなパッチも投げているくらいなので、ここをカスタマイズしたい。
サーバーサイドのホスト名は SHOW GLOBAL VARIABLES LIKE 'hostname'
で取れて、MySQL Shellのプロンプトには SHOW GLOBAL VARIABLES
の値を取ってくるための %sysvar:*%
パラメーターがあるので、これを使ってみる。
$ cat ~/.mysqlsh/prompt.json
{
"prompt": { "text": "%user%@%sysvar:hostname% [%schema%]> " }
}
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@150-95-141-50 [d1]>
よし行けた。
ついでによく見たくなる、「そのホストが read_only
かどうか」も積んでみる。
$ cat ~/.mysqlsh/prompt.json
{
"prompt": { "text": "%user%@%sysvar:hostname% [%schema%] (%sysvar:read_only%)> " }
}
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@150-95-141-50 [d1] (OFF)>
0か1になると思ったら案外OFF表記だった。
このままだと何が何だかわからないので、 read_only
だったら「READ_ONLY」、そうでなければ「READ_WRITE」とか表示させたい。
カスタム変数とかいうのがあるのでそれを使う。
$ cat ~/.mysqlsh/prompt.json
{
"variables":
{
"read_only_str":
{
"match":
{
"pattern": "OFF",
"value": "%sysvar:read_only%"
},
"if_true": "READ_WRITE",
"if_false": "READ_ONLY"
}
},
"prompt": { "text": "%user%@%sysvar:hostname% [%schema%] (%read_only_str%)> " }
}
パッと他のサンプルのJSONファイルを覗いて見るに、条件分岐に使えるのは match
しかなさそう。
取り敢えず read_only_str
というカスタム変数を、 OFF
にマッチしたら READ_WRITE
, マッチしなければ READ_ONLY
にセットする。prompt
からは %read_only_str%
を呼び出すようにしてトライ。
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@150-95-141-50 [d1] (READ_WRITE)>
上手くいった。
ところでこれ、途中で値を変えたらどうなるんだろ。
root@150-95-141-50 [d1] (READ_WRITE)> \sql SET GLOBAL read_only = 1;
Fetching table and column names from `d1` for auto-completion... Press ^C to stop.
Query OK, 0 rows affected (0.0003 sec)
root@150-95-141-50 [d1] (READ_ONLY)>
おお、読み直した。
他のセッションから値を変えたらどうかな?
mysql80 22> SET GLOBAL read_only = OFF; -- 別ターミナルのmysqlコマンドラインクライアントから
Query OK, 0 rows affected (0.00 sec)
root@150-95-141-50 [d1] (READ_ONLY)>
root@150-95-141-50 [d1] (READ_WRITE)> /* 空Enter打ったタイミングで変わった */
root@150-95-141-50 [d1] (READ_WRITE)>
プロンプトを描画するたびに毎回フェッチしてるっぽい。
よしよし、良いんではないか。
と思いつつ今日はここまで。
【2022/03/03 00:38】
続き -> 日々の覚書: MySQL Shellのプロンプトをゼロからカスタマイズしてみんとす(classとsegment)
0 件のコメント :
コメントを投稿