快適mysqlコマンド★カスタマイズの決定版

この記事は MySQL Casual Advent Calendar 2013 の25日目の記事です。

自分の過去のブログも含めて、mysqlコマンドのカスタマイズについていろいろな情報がありますが、わたしがオススメの秘伝のタレをまとめたいと思います。是非、ご参考に。

定型文(SQL)のショートカット入力

「show create table TABLENAME\G」とか「select user,host,password from mysql.user order by user,host;」とか、よく実行するけど長くて入力するのがめんどうなのがありますよね。それをショートカットで入力できるようにする方法です。

mysqlコマンドで行編集ができるのは、readlineやlibeditをリンクしているおかげです。

従来の公式バイナリ配布物に含まれるmysqlコマンドはreadlineでしたが、少なくとも5.6のはlibeditを使っているようです。(以前からライセンスの関係で商用版はlibeditだと思います)

readlineは~/.inputrcで、libeditは~/.editrcに設定を書くことによって、ショートカットキーと行編集等のライブラリのコマンドを紐付けることができるのですが、コマンドではなくただの文字列に展開することもできます。

これを活用すると、長いSQLもショートカットキーでさくっと入力できて捗ります。

# .inputrc
$if mysql
"\C-xd": "show databases;"
"\C-xt": "show tables;"
"\C-xu": "select user,host,password from mysql.user order by user,host;"
"\C-xb": "select user,host,db       from mysql.db   order by user,host;"
"\C-xc": "show create table TN\\G"
"\C-xn": "select count(*) from ;"
"\C-xv": "show variables like '%%';"
"\C-xs": "show slave status\\G"
"\C-xm": "show master status\\G"
"\C-xp": "show full processlist;"
"\C-xa": "show table status like 'TN'\\G"
$endif
# .editrc
mysql:bind '^U' vi-kill-line-prev
mysql:bind '^W' ed-delete-prev-word
mysql:bind '^R' em-inc-search-prev

mysql:bind -s "^xd" "show databases;"
mysql:bind -s "^xt" "show tables;"
mysql:bind -s "^xu" "select user,host,password from mysql.user order by user,host;"
mysql:bind -s "^xb" "select user,host,db       from mysql.db   order by user,host;"
mysql:bind -s "^xc" "show create table TN\\\\G"
mysql:bind -s "^xn" "select count(*) from ;"
mysql:bind -s "^xv" "show variables like '%%';"
mysql:bind -s "^xs" "show slave status\\\\G"
mysql:bind -s "^xm" "show master status\\\\G"
mysql:bind -s "^xp" "show full processlist;"
mysql:bind -s "^xa" "show table status like 'TN'\\\\G"

スキーマ名の補完

mysqlコマンドで「rehash」と実行すると、データベース名、テーブル名、カラム名などがタブで補完できるようになり、たいへん捗ります。

useでデータベースを移動したときなどに、いちいち「rehash」するのはめんどうなので、mysql --auto-rehash や ~/.my.cnf の[mysql]セクションに auto-rehash と書いておくとよいです。

# ~/.my.cnf
[mysql]
auto-rehash

ただ、大量にテーブルがあるデータベースでは、rehashの処理に時間がかかり作業効率が逆に落ちてしまうので、そういった場合はしかたないのでauto-rehashは止めて手動rehashにせざるを得ないですね。。。

プロンプトのカスタマイズ

みんなだいすきプロンプトのカスタマイズ。

自分の場合はこんなふうにユーザー名、ホスト名、DB名を表示するようにしています。

# ~/.my.cnf
[mysql]
prompt="\\u@\\h[\\d]> "

さて、シェルのプロンプトに色をつけて視認性を高めている方は多いと思います。できればmysqlコマンドのプロンプトにも色を付けたい!!

端末が認識する色のエスケープシーケンスについてはこのへんを参照するとよいです。

例えばbashなら

$ echo -e "I love \e[31mApple\e[0m :D"
I love Apple :D

と実行すると、「Apple」のところだけ赤くなるはずです。

これを使えば簡単にmysqlコマンドのプロンプトにも色をつけられそうですが、さてこの「\e」(「\033」「\x1b」も同じ意味です)は16進数で0x1Bに展開されるのですが、だれが展開してるかというとシェルです。

なので、「mysql --prompt "\e[31m\\u\e[0m> "」としても期待通りに色は付かないので、エスケープシーケンスではなく0x1Bな値を埋めむ必要があります。

その方法はいくつかあります。

echo -e しちゃうとか、

$ mysql --prompt="$(echo -e '\e[31m\\u\e[0m> ')"

C-q ESC (readlineだと quoted-insert) で入力しちゃう(画面上は「^[」に見えるけど1文字扱いになる)とか、

# ~/.my.cnf
prompt="^[[36m\\u^[[0m> "

です。

ラッパースクリプト書けばオプションを元に root だったら \u を赤く太くするとか、ホスト名を見てマスター、スレーブ、バックアップで色を変えるとかもできそうですね。



こんな素敵な色付けですが、長い文字列(SQL文)を入力すると、ターミナル幅より前で折り返しされてしまいます。

これは色付けのためのエスケープシーケンスも文字数としてカウントしてしまっているからです。

bashの場合は、「\[ ... \]」で囲めば表示はするけど文字数として勘定しないようにできるのですが、mysqlコマンドにはそういったものがないので、がまんするか、プロンプトの最後に\nを入れて改行するかだと思います。(よい方法があったら教えてください><)


それでは良いお年を!!!