試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

256色拡張の端末で色変更を比較的簡単に行うための変数を定義するスクリプトを作成

16色の端末では、色ごとに

COLOR_DEFAULT='\e[0m'
COLOR_BLACK='\e[1;30m'
COLOR_RED='\e[1;31m'
...

のように変数を定義して

echo ${COLOR_RED}red${COLOR_DEFAULT}

のように書くことで、色の変更を分かりやすく記述することができる。
256色拡張でも要領は同じなのだが、色の数が多く、「RED」などの名前を付けられる色も限られてしまうため、全ての色をカバーするのは難しい。
そこで、その色定義部分を処理するスクリプトを作成し、別のシェルスクリプトから呼び出して簡単に使えるようにした。

コード

色の指定は「${COLOR_FG_FFAF00}」のように、16進形式のコードで表記する。使用可能な色は「端末の256色拡張の色(パレット)について」を参照。色指定に加え、太字とネガ(前景色と背景色を反転)もスタイル指定として簡単に扱えるようにした。
(2008/7/5)下のコードは実行に時間がかかるため、スクリプトを自動生成することでこの問題を解決した。「256colorlib.shをスクリプトから生成して動作を高速化・更にzshのプロンプトの色変更にも使用できるようにする」を参照。


ファイル名: 256colorlib.sh

# 256colorlib.sh - 256色拡張の色指定を定義
# (C) 2008 kakurasan

# ライセンス : GPL-3
# 対応シェル : bash, zsh
# 使用例     : . 256colorlib.sh もしくは source 256colorlib.sh

# 定義される変数
#  COLOR_FG_rrggbb : 前景色を#rrggbbに変更
#  COLOR_BG_rrggbb : 背景色を#rrggbbに変更
#  STYLE_DEFAULT   : 色とスタイルをリセット
#  STYLE_BOLD      : 太字
#  STYLE_LINE      : 下線
#  STYLE_NEGA      : 前景色と背景色を入れ替える
#  STYLE_NOLINE    : 下線なし

# シェル判別
if test -n "${BASH_VERSION:-}"; then
  USE_BASH=1
else
  USE_BASH=0
  if test -z "${ZSH_VERSION:-}"; then
    echo "256colorlib: error: this script supports bash or zsh." >&2
    exit 1
  fi
fi

# スタイルの指定と解除
STYLE_DEFAULT='\e[0m'
STYLE_BOLD='\e[1m'
STYLE_LINE='\e[4m'
STYLE_BLINK='\e[5m'
STYLE_NEGA='\e[7m'
STYLE_NOLINE='\e[24m'

# カラーキューブ色: 216色(16-231)
# 16 + ( [赤成分(0-5)] x 36 ) + ( [緑成分(0-5)] x 6 ) + ( [青成分(0-5)] x 1 )
# R(赤)/G(緑)/B(青)各成分は0から5の値をとり
# 色コードはそれぞれ「0x00 0x5F 0x87 0xAF 0xd7 0xFF」となる
# (「0x00 0x33 0x66 0x99 0xCC 0xFF」では *ない* )
COLORS=("00" "5F" "87" "AF" "D7" "FF")
# bashのときに配列全体を1番からにずらす
[[ ${USE_BASH} -eq 1 ]] && COLORS=("" ${COLORS[@]})
for X in {16..231}; do
  # 最後の「+1」はzshに合わせて1番から始まる形に合わせている
  R=$(( ( ${X} - 16 ) / 36 + 1 ))
  G=$(( ( (${X} - 16 ) % 36 ) / 6 + 1 ))
  B=$(( ( (${X} - 16 ) % 6 ) / 1 + 1 ))
  # evalで実際の代入を行う
  eval "COLOR_FG_$(printf %s%s%s ${COLORS[${R}]} ${COLORS[${G}]} ${COLORS[${B}]})='\e[38;5;${X}m'"
  eval "COLOR_BG_$(printf %s%s%s ${COLORS[${R}]} ${COLORS[${G}]} ${COLORS[${B}]})='\e[48;5;${X}m'"
done
unset R G B COLORS X

# グレイスケール色: 24色(232-255)
COLORS=("08" "12" "1C" "26" "30" "3A" "44" "4E" "58" "62" "6C" "76"
        "80" "8A" "94" "9E" "A8" "B2" "BC" "C6" "D0" "DA" "E4" "EE")
# 上と同様にbashの要素ずらしを行う
[[ ${USE_BASH} -eq 1 ]] && COLORS=("" ${COLORS[@]})
for X in {232..255}; do
  G=$(( ${X} - 232 + 1 ))  # R/G/Bの全てに共通
  eval "COLOR_FG_$(printf %s%s%s ${COLORS[${G}]} ${COLORS[${G}]} ${COLORS[${G}]})='\e[38;5;${X}m'"
  eval "COLOR_BG_$(printf %s%s%s ${COLORS[${G}]} ${COLORS[${G}]} ${COLORS[${G}]})='\e[48;5;${X}m'"
done
unset G COLORS X USE_BASH

# [EOF]

(2008/7/5)下線のスタイルに関する記述を追加

使用例

そのままではbashで動作するが、最初の行を「#! /bin/zsh」にするか、zshの引数にしてzshで実行した場合にも同様に動作する。
[任意]ファイル名: 256colorlib-test.sh

#! /bin/bash

. 256colorlib.sh

echo -e ${COLOR_FG_FFAF00}fgcolor:#ffaf00 bgcolor:default style:default${STYLE_DEFAULT}
echo -e ${COLOR_FG_C6C6C6}${STYLE_NEGA}fgcolor:#c6c6c6 bgcolor:default style:nega${STYLE_DEFAULT}
echo -e ${COLOR_FG_5FAF5F}${STYLE_BOLD}fgcolor:#5faf5f bgcolor:default style:bold${STYLE_DEFAULT}
echo -e ${COLOR_BG_0087AF}fgcolor:default bgcolor:#0087af style:default${STYLE_DEFAULT}
echo -e ${COLOR_FG_5FD75F}${COLOR_BG_626262}${STYLE_BOLD}fgcolor:#5fd75f bgcolor:#626262 style:bold${STYLE_DEFAULT}

実行結果(端末の背景色は黒にしてある)

呼び出すのに時間がかかるのが嫌な場合

256colorlib.shは計算やフォーマット処理、代入といった処理をループで繰り返し行っているため、呼び出すときに時間がかかるという欠点を持つ。
これを使用したスクリプトを実行する度に.もしくはsourceすると遅いので、一度シェル上で

. [256colorlib.shの場所]

をするか、シェルの初期化ファイル(${HOME}/.bashrc${ZDOTDIR}/.zshrc)にこれを書いてから

. [実行したいスクリプト]

で(「. [256colorlib.shの場所]」の部分を取り除いた)スクリプトを実行すると、(定義したシェル変数が保持されるため)色の定義がされた状態で対象のスクリプトが実行できる。
(2008/7/5)この方法は非推奨とする。

関連記事:

関連URL(全て英語):

使用したバージョン:

  • xterm 235
  • bash 3.2_p33
  • zsh 4.3.4(4.3.4-r1)