Consolez vous par procuration

Publié le 14 octobre 2007 par Peck
Le retour de l'article sur http://linux-attitude.fr/post/Consolez-vous-par-procuration

Niveau
:
Résumé : cat /dev/vcs1

Parfois, vous voulez lire le contenu de la console d'une machine, par exemple si vous êtes sur une machine distante et que vous vouliez vérifier ce qui se passe, ou que vous êtes une grosse feignasse qui refuse de taper ctrl-alt-f1. Enfin vous pourrez aussi lire ce qui se passe sur le terminal qui est derrière votre serveur X (en général rien). Alors je vais tout vous expliquer.

Linux propose plusieurs device pour lire ses terminaux. Ils s'appellent /dev/vcsX et /dev/vcsaX. Selon les systèmes, il peuvent aussi se trouver dans le répertoire /dev/vc/X (X étant le numéro du terminal).

Il existe plusieurs méthodes pour en lire le contenu, il faut dans tous les cas être root pour le lire (ls -l /dev/vcs* pour vérifier). Tout d'abord intéressons-nous à vcs1, celui-ci contient uniquement le texte du terminal.

À l'ancienne :
# 1 pour le premier terminal et fd/1 pour stdout
$ setterm -dump 1 -file /proc/self/fd/1

Méthode ultra simple, attention, il faut que votre terminal en cours fasse la même largeur que le terminal à lire (en général 80 colonnes) :
$ cat /dev/vcs1

Même chose mais sans les inconvénients :
$ fold -w 80 /dev/vcs1 & echo -e "n"


Mais tout ceci n'inclue pas les couleurs ni la position du curseur. vcsa1 contient ces informations. Pour les afficher proprement je vous ai péparé un petit script perl.

#!/usr/bin/perl
# Affiche /dev/vcsa1 si aucun argument n'est passé
$dev = $ARGV[0] || "/dev/vcsa1";
open(VCS,$dev);
# lit les dimensions
read VCS,$a,1; read VCS,$b,1;
$width = ord($b);
$height = ord($a);
# lit la position du curseur
read VCS,$a,1; read VCS,$b,1;
$x = ord($a);
$y = ord($b);
# lecture du contenu
$i=0;
$j=0;
while(read(VCS,$c,1))
{
   # $c caractère, $a attribut (1bit graisse + 3 bits couleur)
   read VCS,$a,1;
   $attr = ord($a);
   $bold = $attr >> 3;
   $color = ($attr & 0x7)+30;
   # affichage du caractère grâce aux séquences ANSI
   if($i == $x & $j == $y)
   {
   # curseur -> souligné
   print "x1b[${bold};4;${color}m${c}";
   }
   else
   {
   print "x1b[${bold};${color}m${c}";
   }
   # Affichage du retour a la ligne au bon endroit
   if(++$i == $width)
   {
   print "n";
   $i=0;
   $j++;
   }
}
# fin
close(VCS);
print "x1b[00m";



Et enfin notez qu'il est possible d'écrire dans /dev/vcsX et /dev/vcsaX, marrant pour faire des blagues. Par exemple tapez-y en root sans valider
$ rm -rf /

Puis sauvegardez (depuis un autre terminal) :
$ cat /dev/vcsa1 > /tmp/save

Videz l'écran (ctrl-l, déconnectez vous) puis depuis le 2e terminal :
cat /tmp/save > /dev/vcsa1

Le prochain qui passe pensera que quelqu'un est resté connecté et a lancé une commande bien sympatique. Amusez-vous à le rendre plus réaliste en ajoutant des messages d'erreurs dans le fichier sauvegardé.