パスワードを忘れた? アカウント作成
12660269 journal
ソフトウェア

dodaの日記: 背景色でも強調がしたい! 2

日記 by doda

この日記はかなり前に途中まで書かれた後飽きてしばらく寝かされていました。
どれくらい寝かされていたかはタイトルから察してください。

複数の端末ウィンドウを開いて作業している時で、root でログインしているとか本番サーバに入っている場合などに、
特に注意を払って作業をする必要があるウィンドウである事を強調したい事があると思います。
よく使われる方法はプロンプトで目立たせる方法ですが、目立ち方が足りないと思う人がいますし、
vi でファイルの編集をしている時などはそもそもプロンプトが表示されなかったりします。

さらに目立つ方法として、端末の背景(と文字)の色を変えるという事も行われる事があります。
よく行われる方法としては、重要な作業をする場合は他と違う背景色の端末エミュレータを起動して
そこで作業をするという物があります。
しかしこの方法の場合、通常の作業をしている端末で root になった場合には対応できません。
そこで今回紹介するのは、動的な文字/背景色の変更方法です。

端末エミュレータの事実上の標準である xterm には、起動後に文字色,背景色を動的に変更する為の制御文字列があります。
この制御文字列は Tera Term や mlterm, rxvt-unicode, ICE IV 版 PuTTY 等でもサポートされていて、それなりに汎用的に使えます。
この制御文字列を例えば root のプロンプトに埋め込む事によって、root になった時に自動で背景色が変わるようにする事が出来ます。

制御文字列の形式:

   OSC 1 0 ; 色指定 ST      -- 文字色を"色指定"の色に変更する
   OSC 1 1 ; 色指定 ST      -- 背景色を"色指定"の色に変更する
   OSC 1 1 0 ST             -- 文字色をデフォルトの色に戻す
   OSC 1 1 1 ST             -- 背景色をデフォルトの色に戻す

OSC は文字 0x9d の事ですが、通常は7ビット表現である ESC(0x1b) ] が用いられます。

同様に ST(0x9c) は ESC \ が用いられます。
OSC 文字列の終端は正式には ST なのですが xterm 等では BEL(0x07) も使われたりします。
一部の端末(CDE の dtterm 等)では ST を認識せず端末がハングアップしたような状態になる事が有るので、BEL を使用する方が無難かもしれません。

色指定には、通常は #rrggbb のような形式が用いられる事が多いです。
rr, gg, bb は 16 進での 2 桁の値で、それぞれ RGB での赤, 緑, 青の各色の明るさを表します。

動作確認:
接続先のホストで以下のコマンドを実行すると、対応している端末では赤背景に白文字の状態になります。

% echo -e '\e]10;#ffffff\a\e]11;#ff0000\a'

上記の例では文字色を変更する OSC 文字列と背景色を変更する OSC 文字列の二つを使用していますが、
下記のような、一つの OSC 文字列で文字色と背景色を変更する短縮形式が有ります。

% echo -e '\e]10;#ffffff;#ff0000\a'

ただし、この形式は対応していない端末が多いので、いろいろな端末を使う場合は避けた方がいいかもしれません。

以下のように OSC 110, 111 を使うと端末の色をデフォルトにリセットする事が出来ます。

% echo -e '\e]110\a\e]111\a'

ただし一部の端末(rxvt-unicodeやmltermなど)ではこのリセットに対応していないので、これらの端末を使う場合は
OSC 10, 11 で初期状態と同じ色に設定する方がいいかもしれません。

設定:
端末色の変更が確認できたら、後は適切なタイミングで色の変更が行われるようにすれば OK です。
しかし、root へのユーザ変更をどのように行うか、例えば su を使うのか sudo を使うのか、
またオプションに何を指定するのかによって起動するシェルや読み込まれる設定ファイルが変わってきます。
ここでは一つの例として、zsh を使用しているユーザが sudo -Hs を使って root 権限を得る場合の設定を書きます。

まず sudo -Hs で root になった場合、root のホームディレクトリの .zshenv, .zshrc の二つの設定ファイルが読み込まれます。
.zshenv は対話型シェルじゃなくても読み込まれますので、ここでは .zshrc に以下の設定を追加します。

echo -ne '\e]10;#ffffff\a\e]11;#ff0000\a'

これで sudo -Hs で root になった時に端末の色が白文字で赤背景になります。
他の色にしたい場合は、#ffffff, #ff0000 の部分を変更してください。

root になった時に色を変えるだけだと、一般ユーザに戻ってもウィンドウの色が変わったままとなるので紛らわしくなります。
そこで、root から戻った時にウィンドウ色を元に戻すために、.zshrc に以下の行を追加します。

trap 'echo -ne "\e]110\a\e]111\a"' 0

これで sudo -Hs で起動したシェルが終了する時に echo コマンドが実行されて、端末の色がリセットされます。
OSC 110, 111 による色リセットが使えない端末の場合、以下のように別の色(この例では白文字に黒背景)に変更するようにします。

trap 'echo -ne "\e]10;#ffffff\a\e]11;#000000\a"' 0

最後に:
自分の場合はこの設定を入れてはあるのですが、普段は sudo コマンドで必要なコマンドのみを実行するようにしており、
root 権限のシェルを起動する事はほとんど無いので、実際のところこの設定が使われる事がまず無いです。
しかし、ごくまれに一般ユーザが入れないディレクトリへ移動する事が必要になった時などに sudo -Hs を実行して
いきなり背景色が変わって驚くという事を繰り返しています。
背景色が変わると普段とは違う状況だと一目瞭然なので、それなりに役に立っていると思います。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 私の場合、suで入って作業した後、suspendコマンドで親シェルに戻り、特権のまた必要なときにfgで子供のsuプロセスに戻ります(パスワードを入れ直すのが面倒くさいので)。
    SIGSTOPやSIGCONTをtrapしてみたことはないですが、もしできるならSTOPやCONTにも対応するとよいかもしれない。
    --
    ??iida
    • by doda (31157) on 2016年02月02日 15時41分 (#2958328) 日記

      SIGSTOP は trap 出来ないですね。SIGCONT は出来るみたいですけれど。

      実は最初はプロンプトに制御文字列を仕込む形を考えていました。
      この場合、root のプロンプトに色変更を、一般ユーザのプロンプトでリセットを仕込む事になりますが、これならば対応出来そうです。
      設定箇所が複数のユーザに分散するのを嫌ったので最初の説明では使わなかったのですが、
      他の要因で色が変わった(リセットされた)時にも root のプロンプトに戻れば再度設定されるので、
      こちらの方がいいかもしれませんね。

      後は、

      alias suspend='echo -ne "\e]110\a\e]111\a"; suspend'
      trap 'echo -ne "\e]10;#ffffff\a\e]11;#ff0000\a"' CONT

      のように suspend への alias と SIGCONT の trap を組み合わせるという方法もありそうです。

      親コメント
typodupeerror

日本発のオープンソースソフトウェアは42件 -- ある官僚

読み込み中...