ターミナルに表示される user@host:~$
みたいなものは変数 PS1
で設定できると習ったのだが、Ubuntuのデフォルトの設定を見てみるとやけに複雑な形をしていて、何を表しているのかさっぱり分からなかった。
user@host:~$ echo "'$PS1'"
'\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
なので、これを理解するために調べたことをまとめておく。
使用した環境は以下の通り。
- Ubuntu 14.04
- bash 4.3.11
- GNOME端末 3.6.2 (
TERM=xterm
) - (色がつくようにだけ設定変更あり)
.bashrcの内容
パラメーターによる条件分岐や参考になるコメントが書いてあるので、プロンプト設定に関わる部分を抜粋する。なお force_color_prompt=yes
のコメントアウトは外してある。
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
記号の意味
プロンプト用の特殊な文字列
バックスラッシュで始まる特定の文字列は、プロンプトに用いると別の文字列に変換される。
-
\u
: ユーザー名 -
\h
: ホスト名 -
\w
: 現在のディレクトリ(フルパス) -
\$
: ふつうは$
、実効uidが0なら#
-
\[...\]
: 表示しない文字列(ターミナル制御用のもの)はこれで囲っておくこと1 -
\033
,\e
: エスケープ文字 -
\a
: ベル文字
他にもたくさんある。一覧はネットでも man bash
でも調べられるので省略。
変数展開
$変数名
または ${変数名}
と書いてあると、変数の表す文字列に展開される。シェルコマンドやスクリプトの中で使うことが多いが、プロンプトを表示する際にも展開が有効。そのため、変数を定義したら PS1
を再設定しなくても次行のプロンプトにすぐ反映される。
変数をただ展開するだけでなく、変数の状態に応じて処理を変えることもできる。${変数名:+文字列}
は、「変数の値が存在していたら指定の文字列に展開」となる。今回の ${debian_chroot:+($debian_chroot)}
の場合は、例えば debian_chroot=foobar
と定義されていれば文字列 (foobar)
に展開する(つまり丸括弧で囲んで出力)。未定義または空文字列なら何も表示されない。
user@host:~$ debian_chroot="foobar"
(foobar)user@host:~$ debian_chroot=""
user@host:~$ unset debian_chroot
user@host:~$
プロンプトで展開するためには、PS1
を定義する際には展開しないようにする必要がある。そのためには、PS1='$var'
と文字列をシングルクォートで括るか、PS1="\$var"
とエスケープすればいい。(PS1='\$var'
だとバックスラッシュが残って前節の \$
の意味になるのでダメ)
debian_chroot
肝心のこの変数の利用法については、参考に挙げたページの説明が分かりやすかった。
.bashrc
にもある通り、 debian_chroot
には /etc/debian_chroot
の内容を(可能なら)セットしている。この仕組みが役立つのは、chroot
コマンドでルートディレクトリを変えるとき。あるサブディレクトリに別のLinux環境が一式入っている場合、ルートディレクトリをそこへ切り替えれば、全てのパスの指し示す先がサブディレクトリ以下となるため、そのまま別のLinuxを使用する状態にできる。各環境内にあらかじめ /etc/debian_chroot
を用意しておけば、どの環境を使用中かプロンプトから区別することができる。
ASCII制御文字
\e
(\033
), \a
(\007
) はプロンプトの中で制御文字 ESC
, BEL
に変換される。これら自体はまともな文字として表示されないが、決められた一連の文字列を作るとターミナルが特別な動作をする。
文字の装飾
\033[...m
のようになっているところでは色や太字などの制御をしている。使われている番号の意味は以下の通り。
- 0 : 全部リセット
- 1 : 太字
- 32 : 文字色を緑
- 34 : 文字色を青
0番台では太字以外に下線・文字色と背景色の反転などもできる。30番台は文字色、40番台は背景色。
ターミナルのタイトル
\e]0;...\a
はターミナルのタイトルに文字列を表示させる。デフォルト設定の場合は \u@\h: \w
の変換結果が表示される。
.bashrc
では PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
となっているが、全体をダブルクォートで囲っているため変数がその場で展開され、debian_chroot
を後からタイトルに反映させることはできなくなっている。
試してみる
これらの機能はプロンプトに限らず、ターミナルに出力するだけで効果がある。簡単な試し方として、echo
コマンドなら -e
オプションでバックスラッシュ文字列を変換してくれる。
user@host:~$ PS1='\u@\h:\w\$ ' # プロンプトから設定を消しておく
user@host:~$ echo -e '\e[32mfoobar' # 緑字に変更
foobar
user@host:~$ echo -e '\e]0;foobar\a' # タイトル変更
user@host:~$ . ~/.bashrc # 設定を再読み込みすれば大抵は元通り
user@host:~$ echo -ne '\e[0m' # 色が消えなければ手動で消す
user@host:~$ exit # どうしても直らなければ一旦ターミナルを閉じる
目的別まとめ
- プロンプトらしい文字列表示だけなら
PS1='\u@\h:\w\$ '
みたいに短く済む - 変数の内容を表示させたければ
${変数名}
などを埋め込む。echo $PS1
としたときに未展開のまま表示され、\$
ともなっていなければOK-
${変数名:+代替文字列}
や${変数名:-デフォルト文字列}
などを使えばより凝った設定ができる - ちなみに変数展開だけでなく、コマンド置換
$(コマンド)
や算術展開$((式))
も使える
-
- 文字を装飾したければ
\[\e[...m\]
を間に入れる。適宜\[\e[0m\]
などして設定をリセットすること - ターミナルのタイトルを変更したければ
\[\e]0;...\a\]
を加える
参考
- プロンプト全般
- 変数展開
- debian_chroot
- 文字の装飾・ターミナルのタイトル
-
これを使わずに着色設定をしたことがあるが、コマンドを履歴から出したときなどに表示がおかしくなった ↩