ITエンジニアのための勉強会・イベントレポート情報メディア

それゆけ!ターミナル部 第6回Bashをカスタマイズしていい感じにしよう!
skill

それゆけ!ターミナル部 第6回
Bashをカスタマイズしていい感じにしよう!

2017.01.17

 
  • このエントリーをはてなブックマークに追加

みなさんこんにちは!ターミナル部部長のタナカトモフミです。

本連載では意外と見落としがちな基本的な事柄からちょっとマニアックなテクニックまで、ターミナルを使いこなすための方法を若手エンジニアのタミ夫くんとシェルスキー先生と一緒に学んでいきます。

今回はBashのカスタマイズについて見ていきます。第4回ではエイリアスを定義することで自分好みのコマンドを使えるようにしましたが、その他にも様々なカスタマイズが可能です。Bashをカスタマイズして、より自分の使いやすいターミナル環境を追求してみましょう!

タナカトモフミ

とある昼下がり、いつも元気なはずのタミ夫くんがなにやらアンニュイなため息をついています。

あれいいなーなんだかなー。俺にもあんな先輩いたらなー。はぁ・・・

ちょいちょい聞きずてならんな後半部分。何があったんじゃ?

いやー同期が先輩にシェルカスタマイズしてもらって、めっちゃカラフルでイケイケなターミナルにしてたんスよ。
師匠の地味なアドバイスと違って、俺もマジであーゆーイケてる感じのやつがしたいんスよねー。

なんじゃそんなことか。自分でやるなら、わしがカスタマイズ方法を教えてやっても良いぞ。

えーつべこべ言わずにやってくださいよー。説明、長そーだし。

いやいや最終的には、みんな自分にとって良いものへとカスタマイズしていくんじゃから、基本を押さえておくべきじゃ。

Bashをカスタマイズしよう!

シェルをカスタマイズして使いやすくする場合、基本的には以下の4つのカスタマイズを行います。

  • 1. エイリアス (alias)
  • 2. 関数 (function)
  • 3. 補完 (completion)
  • 4. プロンプト (prompt)

エイリアスは第4回で紹介しましたので、今回は関数から見ていきましょう。

関数を定義して使ってみよう!

シェルで実行できるコマンドは以下の3つに分類できます。

1. ビルトインコマンド
○ シェル自身が内蔵しているコマンド
○ 例: cd, test, typeコマンドなど
2. 環境変数PATHに存在する実行可能ファイル
○ スクリプトやバイナリ
○ 例: ls, python
3. ユーザ定義の関数
○ 関数を定義するとコマンドと同じように呼び出すことができます

では早速関数を定義してみましょう。

# hello_world という関数を定義する
# { のあとはEnterキーを押して改行します。2行目以降の > は入力の必要はありません。注意してください。
$ function hello_world {
> echo 'Hello, World!'
> }

$ hello_world
Hello, World!

関数は簡単なワンライナーやエイリアスで表現できるものを超えたちょっと複雑なコマンドを定義するのに使えます。さらに、ワンライナーやエイリアスと組み合わせるための部品となるコマンドによく使われます。エイリアスと同様に 「~/.bashrc」 に定義しておくとよいでしょう。

$ cat ~/.bashrc
function hello_world {
	echo 'Hello, World!'
}

「~/.bashrc」に書いた関数はすぐには反映されません。設定ファイルをリロードするのを忘れないように注意してください。「. ~/.bashrc」を実行すればリロードできます。

定義されている関数の一覧は「typeset」コマンドで確認できます。

$ typeset -F
declare -f hello_world
declare -f shell_session_delete_expired
declare -f shell_session_history_allowed
declare -f shell_session_history_check
declare -f shell_session_history_enable
declare -f shell_session_save
declare -f shell_session_save_history
declare -f shell_session_update
declare -f update_terminal_cwd


# 関数の定義を見ることもできます
$ declare -f hello_world
hello_world ()
{
	echo 'Hello, World!'
}

Bashでは関数で、引数やローカル変数などを扱うこともできます。シェルプログラミングなどの参考情報を読んで勉強しておくとよいでしょう。

補完の設定を理解しよう!

第2回のショートカットの回で、「TAB」や「C-i」による補完を紹介しました。この補完機能は、コマンド名やファイル名の補完だけでなく、コマンドに合わせたオプションはサブコマンドの補完といった高度な補完をすることもできます。

サブコマンド付きの簡単な関数を定義して、その関数の補完の設定をしてみましょう。

まずは、サブコマンドを受け取るコマンドを定義するため、「~/.bashrc」に以下の関数を定義します。

function hello_world {
	local sub_command=$1
	case "$sub_command" in
    	"sub1") echo "Run sub1 commmand!";;
    	"sub2") echo "Run sub2 commmand!";;
    	"sub3") echo "Run sub3 commmand!";;
    	*) echo "sub command not found."
	esac
}

この時点では、「hello_world」コマンドを入力してスペースを空けた後に、TABコマンドで補完を実行しても、サブコマンドを候補に出してくれません。しかし、「hello_world」コマンドは、ファイルを受け取りませんからこれでは補完の意味がありません。

# TABキーを押すとカレントディレクトリのファイルのリストが候補として出てきてしまう
$ hello_world
a.txt   b.txt   c.txt   d.txt

そこで登場するのが、complete コマンドです。completeコマンドを使えば、コマンドごとにそれぞれに適した補完を設定することができます。「~/.bashrc」 に以下の記述を追記してリロードしてみましょう。

function __hello_world {
  local current_word =${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "sub1 sub2 sub3" -- $current_word) )
}

complete -F __hello_world hello_world

上記の設定を行うことで、以下のように「hello_world」コマンドの補完候補にサブコマンドの「sub1 sub2 sub3」が表示されるようになります。

# 補完設定の一覧を表示(hello_worldの補完が設定されいることを確認。されていない場合はリロードをしましょう)
$ complete -p
complete -F __hello_world hello_world

$ hello_world sub
sub1  sub2  sub3

このように補完をカスタマイズすることで、より簡単に目的のコマンドが実行できるようになります。しかしながら、全てのコマンドの補完設定を、自分で作るのは大変です。一般的なコマンドには、Bash用の補完の設定スクリプトが付属されていることがありますので、そちらを使うようにしましょう。

# 例: homebrewでインストールしたgitの補完設定を読み込む
$ . /usr/local/etc/bash_completion.d/git-completion.bash

# 補完設定の一覧にgitの補完が追加されていることを確認する
$ complete -p
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git
complete -o bashdefault -o default -o nospace -F __git_wrap__gitk_main gitk

# git s まで入力してTABを押すと sから始まるサブコマンドが候補として表示される
$ git s
send-email	show      	sp        	stage     	status    	subtree
shortlog  	show-branch   st        	stash     	submodule 	svn

このように補完用の設定がすでに存在するケースも多々ありますので、なるべく自作せずに使うと良いでしょう。

プロンプトをカスタマイズして
イケイケな見た目にしよう!

次にもっとも華やかなプロンプトのカスタマイズ方法について見てみましょう。プロンプトは、画面に表示されているコマンドの前に表示されているテキストのことです。通常は、ホスト名やユーザ名が表示されています。Mac OS Xではデフォルトでは以下の表示になります。

hostname:~ username$

毎回目にする場所になりますが、開発マシンではホスト名やユーザ名はいつも同じものが表示されていることも多いため、最近では、開発者向けにGitのリポジトリのブランチ名や未コミットの変更があるかを表示する人が増えてきています。

このプロンプトをカスタマイズする方法は非常に簡単で、「PS1」という環境変数を置き換えるだけです。

# 現在のプロンプトの設定内容を表示する
hostname:~ username$ echo $PS1
\h:\W \u\$

# プロンプトの表示内容を変更する。PS1の中身を変更する。
hostname:~ username$ PS1='$ '

# プロンプトの表示内容が 「$」だけになる
$

このように非常に簡単にカスタマイズできます。元のプロンプトの設定には「\h」といった記号が書かれています。これはプロンプト用の特殊な値で、ホスト名やユーザ名・現在のディレクトリといったよく使われる項目をあらかじめ定義してくれているものです。代表的なものには以下があります。

記号説明
\h ホスト名
\W 現在(カレント)のディレクトリ
\u ユーザ名
\$ rootのユーザの場合は「#」、それ以外のユーザの場合は「$」を表示する
\d 日付の表示。「Mon Nov 28」の形式
\D{format} フォーマットを指定して日時を表示する。strftimeのフォーマットで指定できる
例: 「\D{%Y-%m-%d}」(2016-11-28)
\t 時刻の表示。「HH:MM:SS」形式で24時間表記

さらに、プロンプトに色をつけてカラフルにすることもできます。

$ PS1='\[\e[0;32m\]$\[\e[m\] '

見づらいですが、「\[\e[0;34m\]」で色を指定しており、それ以降に表示される文字の色が「\[\e[m\]」の部分まで変わります。「1:32m」がどんな色かを表すコードです。今回は「$」が囲まれており、「$」の色が以下のように変化します。

代表的な色のコードを以下に示します

コード
0;30m
0;31m
0;32m
0;33m
0;34m
0;35m
0;36m シアン
0;37m

さらに、コマンドの呼び出した結果をプロンプトに表示することもできます。これを活用して、Gitの状態をプロンプトに表示することができます。

$ PS1='$(git describe --contains --all HEAD) $ '

master $

上の例ではgitコマンドの結果をそのまま表示していますが、実際にはGitリポジトリにいない場合には、エラーが出てしまいます。また、PS1の設定が長くなりやすく、読めなくなることもあります。そのため、プロンプト用の便利関数を定義して、それを呼び出すパターンが多用されています。

プロンプトのカスタマイズはジェネレーターを提供しているサイトもあります。以下のサイトなどを参考にしてみるとよいでしょう。

http://omar.io/ps1gen/
http://bashrcgenerator.com/
http://ezprompt.net/

まとめ

やばいっス。カスタマイズ方法がわかったんでちょっとやる気出てきたっスわー。

それはよかったのう。頑張って自分好みに仕上げるんじゃぞ。

30分後...

いやーやっぱ無理っスね。やめたやめた。こだわり始めたら無限に時間かかるわー。

えー。あきらめるの早くないか?

やっぱ俺、手軽にチョチョイでいい感じになればそれでいいっスわー。
どうせなんかあるんでしょ? 早く出してくださいよー。

ふふふ。やはりそうきたか。
ならばお主のような子のために、お手軽にチャチャっとカスタマイズする方法を伝授してやろうではないか。

Bashは様々なカスタマイズが可能で、自分の使いやすいよう試行錯誤してカスタマイズするのも楽しみのひとつなのですが、どうやらタミ夫くんには面倒だったようです。次回はそんなタミ夫くんのためにBashをお手軽にカスタマイズするためのBash-iItを紹介したいと思います。お楽しみに!

原稿: 株式会社ビズリーチ ターミナル部部長 タナカトモフミ

株式会社ビズリーチ所属。ScalaコードをVimで書く日々をおくる。たまにうっかりIntellij IDEAに浮気してしまう。社内のVim部とEmacs部を和解させ、ターミナル部に統合することに成功したが、社内はEclipse, Intellij IDEA, Sublime Text, Atomが主流のため、戦いは続く。

https://twitter.com/tanacasino

それゆけ!ターミナル部 第6回Bashをカスタマイズしていい感じにしよう!

この記事はどうでしたか?

おすすめの記事

キャリアを考える

BACK TO TOP ∧

FOLLOW