mercredi 19 décembre 2007

Erreur bash : "value too great for base"

J'ai rencontré le problème suivant qui a résisté à toutes mes recherches de solution via les classiques moteurs de recherche... mais pas à quelques bonne minutes devant un vrai bouquin (si si ca existe encore et c'est parfois mieux que Google ou Wikipedia...).

Bref, voici le problème initial :
Dans un script unix utilisant bash comme interpreteur, j'ai eu ce message d'erreur
-bash: 08: value too great for base (error token is "08")
Ici bash nous indique qu'il ne peut pas affecter la valeur "08" à une variable. En effet le '0' en premiere position indique au shell qu'on est en octal i.e. base 8. Les seuls chiffres autorisés seront donc entre 0 et 7 (d'où le message "valeur trop grande pour cette base")

La solution :
On précise explicitement la base utilisée grâce à la syntaxe BASE#NOMBRE

Exemple :
$ declare -i NUM
$ NUM=08
-bash: 08: value too great for base (error token is"08")
$ NUM=10#08
$ echo $NUM
8
$ NUM=16#AF5E
$ echo $NUM
44894

vendredi 14 décembre 2007

Utiliser tput et terminfo (2)

Un exemple d'utilisation avancée des fonctionnalités de tput et terminfo.

# save your prompt
PS1_SAVE=$PS1
# set the prompt to blank
PS1=''
# save the number of colums of the terminal
COLUMNS=$(tput cols)
# save the number of lines of the terminal
LINES=$(tput lines)
# set the message you want to display (here it's "hello I am at the center of the term")
message="coucou je suis au milieu du terminal"
# get the horizontal position to center your text
hpos=$(expr $LINES / 2)
# get the vertical position to center your text
vpos=$(expr \( $COLUMNS - $(echo "$message" | wc -c) \) / 2)
# move the cursor to that position
tput cup $hpos $vpos
# enter in reverse video mode
tput rev
# display the message
echo "$message"
# wait for 3 second to see the message
sleep 3
# recall your default prompt
PS1=$PS1_SAVE
# reset all terminal settings
tput sgr0
# clear the screen
tput clear

Changer l'encodage des caractères de l'invite de commande Windows

Vous utilisez la ligne de commande Windows (cmd.exe) et souhaitez que les caratères européens (accents...) soient correctement affichés. Dans ce cas, 2 paramètres sont à changer : le codepage et la police de caractère !

Le codepage :

Par défaut, windows utilise DOSLatin1 (codepage 850) dans son invite de commande (cmd.exe). Nous souhaitons passer à WinLatin1 (codepage 1252).

Pour ce faire vous pouvez utiliser la commande chcp <num> qui vous permettra de changer le codepage à la volée, ou bien modifier la valeur de la clé de registre HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP (redémarrage nécessaire).


La police de caractère :
Dans les propriétés de l'invite de commande Windows, onglet "Police", choisissez
la police "Lucida Console" en lieu et place de "Polices Raster"

Utiliser tput et terminfo

Comment créer des scripts unix avec une UI avancée ?
Essayez de vous souvenir de quelques unes de ces commandes et de les approfondir grâce aux pages de manuel :

# save cursor position
tput sc
# move cursor to 10th line and 20th column
tput cup 10 20
# write some text from here in standout mode
tput smso
echo "j ecris a partir de la 10eme ligne et la 20eme colonne"
# restore cursor position
tput rc
# exit from standout mode
tput rmso



Pour approfondir :
  • man tput
  • man terminfo
  • man termcap

Caractères spéciaux non reconnus

Les touches speciales de votre clavier ne sont pas toujours reconnus lorsque vous vous connectez sur une machine en ssh ? Vous avez réussi à configurer PuTTY pour gérer correctement la touche "backspace", mais il vous manque toujours d'autres controles (Ctrl-C, Ctrl-Z...) ?

Bref vous n'avez pas accès à toutes les fonctions de votre clavier.

Utilisez la commande stty !
Par exemple, sur un de mes serveurs HP-UX 11.11 j'ai ajouté la ligne suivante dans mon .profile :
stty erase "^H" kill "^U" intr "^C" eof "^D" susp "^Z"
Pour une meilleure portabilité, il est possible d'interroger directement la base de donnée terminfo/termcap et d'attribuer le caractere associé à la fonction souhaitée. Par exemple pour l'effacement de caractère :
sttry erase $(tput kbs)