Verder Terug Inhoud

6. ANSI Escape Sequences: Kleuren en Cursorverplaatsing

6.1 Kleuren

Zoals hierboven aangegeven moeten niet-afdrukbare tekens worden omsloten door \[\033[ en \]. Voor kleuren escape sequences, zouden ze ook gevolgd moeten worden door een kleine letter m.

Als je de volgende prompts in een xterm uitprobeert en bemerkt dat je geen kleuren benoemd ziet, controleer dan het bestand ~/.Xdefaults (en mogelijk zijn broeders) op regels als "XTerm*Foreground: BlanchedAlmond". Maak er een commentaarregel van door er een uitroepteken ("!") voor te plaatsen. Natuurlijk zal dit ook afhangen van welke terminal-emulator je gebruik maakt. Dit is de meest waarschijnlijke plaats waar de voorgrondkleuren van je term zouden kunnen zijn overschreven.

Om blauwe tekst in de prompt op te nemen:

PS1="\[\033[34m\][\$(date +%H%M)][\u@\h:\w]$ "

Het probleem met deze prompt is dat de blauwe kleur die met kleurcode 34 begint nooit naar de reguliere kleur wordt teruggezet, dus alle tekst die je achter de prompt intikt staat nog steeds in de kleur van de prompt. Dit is ook een donkere vorm blauw dus het zou kunnen helpen het te combineren met de code bold:

PS1="\[\033[1;34m\][\$(date +%H%M)][\u@\h:\w]$\[\033[0m\] "

De prompt staat nu in lichtblauw en het eindigt door het terugschakelen van de kleur naar niets (welke voorgrondkleur je voorheen ook had).

Dit is de rest van de kleur-equivalenten:

Zwart       0;30     Donkergrijs  1;30
Blauw       0;34     Lichtblauw   1;34
Groen       0;32     Lichtgroen   1;32
Cyaan       0;36     Lichtcyaan   1;36
Rood        0;31     Lichtrood    1;31
Violet      0;35     Lichtviolet  1;35
Bruin       0;33     Geel         1;33
Lichtgrijs  0;37     Wit          1;37

Daniel Dui (ddui@iee.org) wijst erop dat om strikt accuraat te zijn. We moeten aangeven dat de lijst hierboven voor kleuren onder de console is. In een xterm, is de code 1;31 niet "Lichtrood," maar "Benadrukt Rood." Dit geldt voor alle kleuren.

Je kunt ook achtergrondkleuren verkrijgen door 44 te gebruiken voor de Blauwe achtergrond, 41 voor een Rode achtergrond, enz. Er zijn geen benadrukte achtergrondkleuren. Er kunnen combinaties worden gebruikt, zoals Lichtrode tekst op een Blauwe achtergrond: \[\033[44;1;31m\], alhoewel het apart instellen van de kleuren beter schijnt te werken (bv. \[\033[44m\]\[\033[1;31m\]). Andere beschikbare codes zijn 4: Underscore, 5: Blink, 7: Inverse, en 8: Concealed.

Ter zijde: Veel mensen (inclusief mezelf) hebben zeer veel bezwaar tegen het "blink" kenmerk. Gelukkig werkt het niet in alle terminal emulators zover ik weet, maar het werkt nog steeds op de console. En mocht je het je afvragen (zoals ik deed) "Waarvoor een 'Concealed' kenmerk te gebruiken?!" - Ik zag dat het in een voorbeeld shell-script (geen prompt) werd gebruikt om iemand toe te staan een wachtwoord in te typen zonder dat het naar het scherm werd teruggekaatst.

Gebaseerd op een prompt genaamd "elite2" in het Bashprompt package (wat ik heb gewijzigd om het beter te laten werken op een standaardconsole, in plaats van met de speciale vereiste xterm-fonts om de originele goed te kunnen zien), is dit een prompt die ik veel heb gebruikt:


 
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 "
}

Voor de leesbaarheid definieer ik de kleuren als tijdelijke shell-variabelen. Het is makkelijker om er mee te werken. De "GRAD1" variabele is een controle om vast te stellen op welke terminal je je bevindt. Zoals de test om vast te stellen of je in een Xterm aan het werken bent, hoeft het slechts éénmaal te worden gedaan. De prompt ziet er ongeveer zo uit, behalve dan in kleur:

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

Om mezelf eraan te helpen herinneren welke kleuren beschikbaar zijn, schreef ik het volgende script die alle kleuren naar het scherm echoot:


#!/bin/bash
#
#   Dit bestand echoot veel kleurcodes naar de terminal om te demonstreren
#   wat beschikbaar is. Iedere regel bestaat uit één kleur met
#   als achtergrond zwart en grijs, met de code in het midden. Geverifieerd 
#   dat het met een witte, zwarte en grijze achtergrond werkt (2 Dec 98). 
#
echo "  Op Lichtgrijs::        Op Zwart:"
echo -e "\033[47m\033[1;37m  Wit        \033[0m\
 1;37m \
\033[40m\033[1;37m  Wit        \033[0m"
echo -e "\033[47m\033[37m  Lichtgrijs   \033[0m\
   37m \
\033[40m\033[37m  Lichtgrijs   \033[0m"
echo -e "\033[47m\033[1;30m  Grijs         \033[0m\
 1;30m \
\033[40m\033[1;30m  Grijs         \033[0m"
echo -e "\033[47m\033[30m  Zwart        \033[0m\
   30m \
\033[40m\033[30m  Zwart        \033[0m"
echo -e "\033[47m\033[31m  Rood          \033[0m\
   31m \
\033[40m\033[31m  Rood          \033[0m"
echo -e "\033[47m\033[1;31m  Lichtrood    \033[0m\
 1;31m \
\033[40m\033[1;31m  Lichtrood    \033[0m"
echo -e "\033[47m\033[32m  Groen        \033[0m\
   32m \
\033[40m\033[32m  Groen        \033[0m"
echo -e "\033[47m\033[1;32m  Lichtgroen  \033[0m\
 1;32m \
\033[40m\033[1;32m  Lichtgroen  \033[0m"
echo -e "\033[47m\033[33m  Bruin        \033[0m\
   33m \
\033[40m\033[33m  Bruin        \033[0m"
echo -e "\033[47m\033[1;33m  Geel       \033[0m\
 1;33m \
\033[40m\033[1;33m  Geel       \033[0m"
echo -e "\033[47m\033[34m  Blauw         \033[0m\
   34m \
\033[40m\033[34m  Blauw         \033[0m"
echo -e "\033[47m\033[1;34m  Lichtblauw   \033[0m\
 1;34m \
\033[40m\033[1;34m  Lichtblauw   \033[0m"
echo -e "\033[47m\033[35m  Violet       \033[0m\
   35m \
\033[40m\033[35m  Violet       \033[0m"
echo -e "\033[47m\033[1;35m  Rose         \033[0m\
 1;35m \
\033[40m\033[1;35m  Rose         \033[0m"
echo -e "\033[47m\033[36m  Cyaan         \033[0m\
   36m \
\033[40m\033[36m  Cyaan         \033[0m"
echo -e "\033[47m\033[1;36m  Lichtcyaan   \033[0m\
 1;36m \
\033[40m\033[1;36m  Lichtcyaan   \033[0m"

6.2 Cursorverplaatsing

Met ANSI escape sequences kun je de cursor naar wens op het scherm verplaatsen. Dit is nuttiger voor gebruikersinterfaces met volledig scherm, gegenereerd door shell-scripts, maar kan ook in prompts worden gebruikt. De verplaatsings escape sequences zijn als volgt:

- Positioneer de cursor:
  \033[<L>;<C>H
     Of
  \033[<L>;<C>f
  plaats de cursor op regel L en kolom C.
- Verplaats de cursor N regel(s) omhoog:
  \033[<N>A
- Verplaats de cursor N regel(s) naar beneden:
  \033[<N>B
- Verplaats de cursor N kolom(men) vooruit:
  \033[<N>C
- Verplaats de cursor N kolom(men) terug:
  \033[<N>D

- Maak het scherm schoon en ga naar (0,0):
  \033[2J
- Verwijder tot het einde van de regel:
  \033[K

- Bewaar de cursorpositie:
  \033[s
- Herstel de cursorpositie:
  \033[u

De laatste twee codes worden NIET door veel terminal-emulators in acht genomen. De enige die ik ken zijn xterm en nxterm, zelfs al is de meerderheid van terminal-emulators gebaseerd op xterm-code. Zover ik weet, ondersteunen tell, rxvt, kvt, xiterm, en Eterm ze niet. Ze worden op de console ondersteund.

Probeer de volgende regel code achter de prompt te plaatsen (het wordt wat duidelijker als de prompt verscheidene regels lager ligt dan de bovenkant van de terminal, als je dit opgeeft): echo -en "\033[7A\033[1;35m BASH \033[7B\033[6D" Hiermee zou de cursor zeven regels naar boven moeten gaan, het woord "BASH" af moeten drukken en dan terugkeren naar waar het begon om een normale prompt te produceren. Dit is geen prompt, het is gewoon een demonstratie van de cursorbeweging op het scherm, waarbij kleur wordt gebruikt om te benadrukken wat er gebeurde.

Sla dit in een bestand op met de naam "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='+ '
}

Deze prompt is tamelijk kaal, behalve dat het een 24-uurs klok in de rechterbovenhoek van de terminal bijhoudt (zelfs als de grootte van de terminal wordt gewijzigd). Dit zal NIET werken op de terminal-emulators die ik noemde die het opslaan en herstellen van de cursorpositie-codes niet accepteren. Als je deze prompt in één van deze terminal-emulators uitprobeert, zal de klok juist verschijnen, maar de prompt zal op de tweede regel van de terminal worden onderbroken.

Zie ook De Elegant Useless Clock Prompt voor een wat uitgebreider gebruik van deze codes.

6.3 Verplaatsen van de Cursor met tput

Zoals met zoveel dingen onder Unix, zijn er vele manieren om hetzelfde te bereiken. Een utility genaamd "tput" kan ook worden gebruikt om de cursor op het scherm te manoeuvreren, of informatie terug te krijgen over de status van de terminal. "tput" is voor het positioneren van de cursor minder flexibel dan ANSI escape sequences. Je kan de cursor alleen naar een absolute positie verplaatsen. Je kunt het niet naar een positie verplaatsen die relatief is ten op zichte van de huidige positie. Ik maak geen gebruik van "tput", dus ik ga het je hier niet in detail uitleggen. Typ "man tput" en dan zul je net zoveel weten als ik.


Verder Terug Inhoud