次のページ 前のページ 目次へ

5. ANSI エスケープシーケンス: 色とカーソル操作

5.1 色

すでに述べたように表示されないエスケープシーケンスは、\[\033[\] で囲んでやる必要があります。色のエスケープシーケンスの場合は 後ろに m\] をつけてやる必要があります。

もしこれから説明するプロンプトを試してみて、指定した色がうまく表示され ないなら、 /.Xdefaults ファイル(あるいはそれと同等のファイル)に "XTerm*Foreground: BlanchedAlmond" のような行がないか調べてください。 この前に!マークをつけることによって、コメントアウトすることができます。 これは、あなたがどのような端末エミュレータを使っているかにも依存します。 あなたの端末の色が上書きされる可能性のもっとも高いのがこのファイルです。

プロンプトにブルーのテキストを入れるには、

PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$ "
このプロンプトの問題は、34のカラーコードで変えたブルーの色がもとの色に戻らない ので、プロンプトの後にタイプした文字もプロンプトと同じ色になってしまう ことです。また、このブルーは暗いので、bold コードも組み合わせます。
PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0m\] "

プロンプトは明るいブルーに変わり、最後に色をなしにしています。(色なしは、 元のフォアグラウンドカラーです。)

色は次のように定義されています。

Black       0;30     Dark Gray     1;30
Blue        0;34     Light Blue    1;34
Green       0;32     Light Green   1;32
Cyan        0;36     Light Cyan    1;36
Red         0;31     Light Red     1;31
Purple      0;35     Light Purple  1;35
Brown       0;33     Yellow        1;33
Light Gray  0;37     White         1;37

バックグラウンドカラーもこの方法で指定することができます。たとえば44なら ブルー、41なら赤というふうになっています。 バックグラウンドカラーにはボールドのものがありません。 ブルーの背景にライトレッドのテキストを表示するなら、 \[\033[44;1;31m\] のように組み合わせて使うこともできまが、 \[\033[44m\]\[\033[1;31m\] のように分けて設定した方がいいようです。 他のコードとしては、4:下線、5:点滅、7:逆転、8:非表示などがあります。

Aside: Many people (myself included) object strongly to the "blink" attribute. Fortunately, it doesn't work in any terminal emulators that I'm aware of - but it will still work on the console. And, if you were wondering (as I did) "What use is a 'Concealed' attribute?!" - I saw it used in an example shell script (not a prompt) to allow someone to type in a password without it being echoed to the screen. 注:多くの人(私を含め)は、点滅属性に強く反対します。幸いこれは 端末エミュレータでは作動しませんが、コンソールでは機能します。また、 (私がそうであるように)非表示属性は何のためにあるのだろうと思うでしょう。 (プロンプトではなく)シェルスクリプトの例で、パスワードを入力してもスクリーン に表示されないように使われているのを見たことがあります。

Bashprompt パッケージの中の elite2 というプロンプトを(元のが xterm のフォント で用いるようになっていたので、コンソールで使えるように)修正したものは、 私のよく使っていたものです。


 
function elite
{

local GRAY="\[\033[1;30m\]"
local LIGHT_GRAY="\[\033[0;37m\]"
local CYAN="\[\033[0;36m\]"
local LIGHT_CYAN="\[\033[1;36m\]"

case $TERM in
    xterm*)
        local TITLEBAR='\[\033]0;\u@\h:\w\007\]'
        ;;
    *)
        local TITLEBAR=""
        ;;
esac

local GRAD1=$(tty|cut -d/ -f3)
PS1="$TITLEBAR\
$GRAY-$CYAN-$LIGHT_CYAN(\
$CYAN\u$GRAY@$CYAN\h\
$LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
$CYAN\#$GRAY/$CYAN$GRAD1\
$LIGHT_CYAN)$CYAN-$LIGHT_CYAN(\
$CYAN\$(date +%H%M)$GRAY/$CYAN\$(date +%d-%b-%y)\
$LIGHT_CYAN)$CYAN-$GRAY-\
$LIGHT_GRAY\n\
$GRAY-$CYAN-$LIGHT_CYAN(\
$CYAN\$$GRAY:$CYAN\w\
$LIGHT_CYAN)$CYAN-$GRAY-$LIGHT_GRAY " 
PS2="$LIGHT_CYAN-$CYAN-$GRAY-$LIGHT_GRAY "
}

色を一時的シェル変数として読み易いものに定義します。GRAD1 変数は 使っている端末を決めるのに用いています。Xterm 上かどうかのチェックと 同様、これも一度行なえば十分です。結果は色を除けばこのように見えます。

--(giles@nikola)-(75/ttyp7)-(1908/12-Oct-98)--
--($:~/tmp)--

どんな色が使えるのかを思い出すために、次のスクリプトはすべての色をスクリーン にエコーします。


#!/bin/bash
#
#   このファイルは、様々なカラーコードを端末にエコーし、どんな色が
#   使用可能かを示します。
#   それぞれの行では、黒とグレイの背景の上に一つの色を示し、コードを中央に
#   表示しています。白、黒、グリーンの背景色で確認してあります。(2 Dec 98)
#
echo "  On Light Gray:        On Black:"
echo -e "\033[47m\033[1;37m  White        \033[0m\
 1;37m \
\033[40m\033[1;37m  White        \033[0m"
echo -e "\033[47m\033[37m  Light Gray   \033[0m\
   37m \
\033[40m\033[37m  Light Gray   \033[0m"
echo -e "\033[47m\033[1;30m  Gray         \033[0m\
 1;30m \
\033[40m\033[1;30m  Gray         \033[0m"
echo -e "\033[47m\033[30m  Black        \033[0m\
   30m \
\033[40m\033[30m  Black        \033[0m"
echo -e "\033[47m\033[31m  Red          \033[0m\
   31m \
\033[40m\033[31m  Red          \033[0m"
echo -e "\033[47m\033[1;31m  Light Red    \033[0m\
 1;31m \
\033[40m\033[1;31m  Light Red    \033[0m"
echo -e "\033[47m\033[32m  Green        \033[0m\
   32m \
\033[40m\033[32m  Green        \033[0m"
echo -e "\033[47m\033[1;32m  Light Green  \033[0m\
 1;32m \
\033[40m\033[1;32m  Light Green  \033[0m"
echo -e "\033[47m\033[33m  Brown        \033[0m\
   33m \
\033[40m\033[33m  Brown        \033[0m"
echo -e "\033[47m\033[1;33m  Yellow       \033[0m\
 1;33m \
\033[40m\033[1;33m  Yellow       \033[0m"
echo -e "\033[47m\033[34m  Blue         \033[0m\
   34m \
\033[40m\033[34m  Blue         \033[0m"
echo -e "\033[47m\033[1;34m  Light Blue   \033[0m\
 1;34m \
\033[40m\033[1;34m  Light Blue   \033[0m"
echo -e "\033[47m\033[35m  Purple       \033[0m\
   35m \
\033[40m\033[35m  Purple       \033[0m"
echo -e "\033[47m\033[1;35m  Pink         \033[0m\
 1;35m \
\033[40m\033[1;35m  Pink         \033[0m"
echo -e "\033[47m\033[36m  Cyan         \033[0m\
   36m \
\033[40m\033[36m  Cyan         \033[0m"
echo -e "\033[47m\033[1;36m  Light Cyan   \033[0m\
 1;36m \
\033[40m\033[1;36m  Light Cyan   \033[0m"

5.2 カーソル操作

ANSIエスケープシーケンスでカーソルをスクリーン上で自由に動かせます。 これはシェルスクリプトでフルスクリーンのユーザーインターフェースを 作る時に役に立ちますが、プロンプトでも使えます。カーソル操作エスケープ シーケンスは次のとおりです。

- カーソルの位置を決める。
  \033[<L>;<C>H
  カーソルを L 行 C 列に置きます。
- カーソルを N 行上に動かす。
  \033[<N>A
- カーソルを N 行下に動かす。
  \033[<N>B
- カーソルを C 列右に動かす。
  \033[<>C
- カーソルを C 列左に動かす。
  \033[<C>D

- カーソルの位置を記憶する。
  \033[s
- 記憶していたカーソルの位置に戻す。
  \033[u

最後の二つのコードは多くの端末エミュレータで実現されていません。私の知って いる限りでは、xterm と nxterm では実現されています。多くの端末エミュレータが xterm のコードに基づいているにもかかわらず。私が確認した限り、rxvt、kvt、 xiterm、Eterm はサポートしていません。コンソールではサポートされています。

次のコードをプロンプトにいれてみて下さい。(これが何をしているのかをはっきり させるには、端末の上から何行か下でこれを実行して下さい。) echo -en "\033[7A\033[1;35m BASH \033[7B\033[6D" これは、カーソルを7行上に上げて" BASH "と表示し、元のプロンプトのところに カーソルを戻します。これはプロンプトではありません。何が起こっているかを はっきりさせるために色を変えて、カーソルをスクリーン上で動かしてみせている だけです。

次を"clock"という名前のファイルに入れて下さい。


#!/bin/bash

function prompt_command {
let prompt_x=$COLUMNS-5
}

PROMPT_COMMAND=prompt_command

function clock {
local       BLUE="\[\033[0;34m\]"
local        RED="\[\033[0;31m\]"
local  LIGHT_RED="\[\033[1;31m\]"
local      WHITE="\[\033[1;37m\]"
local  NO_COLOUR="\[\033[0m\]"
case $TERM in
    xterm*)
        TITLEBAR='\[\033]0;\u@\h:\w\007\]'
        ;;
    *)
        TITLEBAR=""
        ;;
esac

PS1="${TITLEBAR}\
\[\033[s\033[1;\$(echo -n \${prompt_x})H\]\
$BLUE[$LIGHT_RED\$(date +%H%M)$BLUE]\[\033[u\033[1A\]
$BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
$WHITE\$$NO_COLOUR "
PS2='> '
PS4='+ '
}

このプロンプトで行なわれていることは比較的単純で、端末の右上に24時間制の 時刻が表示されます。(端末のサイズを変えても大丈夫です。)これは、カーソルの 位置の記憶と回復をサポートしていない端末エミュレータではうまくいきません。 そのような端末エミュレータでこれを実行すると、時刻は正確に表示されますが、 プロンプトは端末の2行目から動きません。

これらのコードをもっと沢山使った例は、 役立たずのエレガントな時刻表示プロンプトにあります。

5.3 tput でカーソルを動かす

Unix での多くのことがそうであるように、同じ結果を得るには、二つ以上の方法が あります。tput と呼ばれるユーティリティでもスクリーン上でカーソルを動かせ ます。tput はカーソル操作では ANSI よりも柔軟性が低く、画面上の指定した座標に 動かすことができるだけで、現在の位置から相対的に動かすことはできません。 私は"tput"を使いませんので、これ以上詳しくは説明しません。"man tput"と すれば私の知っていることが分かります。


次のページ 前のページ 目次へ