Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archive for November, 2008

Liens

Nov 28

J'ai un certain nombre de liens en vrac sur des choses intéressantes, mais pour lesquelles je ne prendrai pas le temps d'écrire. Je vous passe ici des liens vers des sites qui en parlent très bien.

Je pense que vous aurez assez de lecture avec ceci, mais je reviendrai ...

Niveau :      
Résumé : tail -F ; ls | wc ; xmodmap ; bell-style ; /proc/sys/kernel/core_pattern

Lire un fichier au fur et a mesure qu'il est complété (par exemple un fichier de log) :

# -F bon réflexe pour les fichier qui peuvent être rotatés
$ tail -F fichier

Compter les entrées d'un répertoire sans se planter avec les noms spéciaux (espace ...) Perdre son temps

$ find . -maxdepth 1 -mindepth 1 -printf a | wc -c

Transformer votre souris en souris pour gaucher :

$ xmodmap -e "pointer = 3 2 1"

Supprimer les bips en bash :

$ set bell-style none

Transformer les bips en flash écran en bash :

$ set bell-style visible

Retour au comportement par défaut :

$ set bell-style audible

Faire apparaitre tous les core dump dans /tmp et non dans le cwd du processus :

# on en profite pour lui donner un nom unique <binaire>-<date>-<pid>.core
$ echo /tmp/%e-%t-%p.core > /proc/sys/kernel/core_pattern

Pour rendre cela persistant au reboot, écrire la ligne suivante dans /etc/sysctl.conf :

kernel.core_pattern=/tmp/%e-%t-%p.core

Niveau :      
Résumé : chmod +x test.c

Après une technique utilisant du perl, voici une nouvelle façon d'utiliser du C aussi simplement qu'un script.

Cette fois nous évitons l'usage de perl, on se passe donc de ses avantages en terme de parsing. Par contre, on utilise un en-tête court et le code fonctionne avec n'importe quel code valide en C. Comme d'habitude, on fait propre et on renvoie le bon code de retour.

#!/bin/sh
tail -n +4 $0 | gcc -Wall -o /tmp/cscript.$$ -x c - && /tmp/cscript.$$ "$@"
ret=$? ; rm -f /tmp/cscript.$$ ; exit $ret
//
// Code C
//
#include <stdio.h>
int main(int argc, char** argv)
{
        printf( "Appel de %s avec %d arguments\n", argv[0], argc-1 );
        return 0;
}

Et maintenant on teste pour prouver que ça marche :

chmod +x test.c
./test.c 1 2 3 && echo "OK" | | echo "KO"

Niveau :      
Résumé : la vie avec unix

Unix, ce n'est pas seulement un système, ce n'est pas seulement une marque, c'est aussi une façon de voir les choses, une façon de concevoir des programmes qui feront ce dont vous avez vraiment besoin. Nous allons parler des principes fondamentaux d'unix.

Tout est fichier

On commence à le savoir, les périphériques sont des fichiers qui se trouvent dans /dev, les processus sont des fichiers qui se trouvent dans /proc, les paramètres et données du noyau sont des fichiers qui se trouvent dans /sys et accessoirement /proc, les exécutables sont des fichiers normaux. Seule la carte réseau n'est pas un fichier, pour des raisons de performances paraît-il. Mais les connexions sont tout de même vues à travers des descripteurs de fichier dans les processus.

Les données sont du texte

Dans la philosophie unix, toutes les données doivent être stockées et transmises sous forme de texte. Cela peut coûter légèrement plus de place qu'un format binaire. Mais on y gagne beaucoup.

  • Un fichier texte peut être lu par les autres outils unix, et donc respecte de principe faire une chose et le faire bien
  • Un fichier texte peut être lu par un être humain et donc respecte le principe kiss
  • Un fichier texte permet une interopérabilité avec d'autres systèmes (pas de problèmes d'indiens en iso par exemple)
  • Un fichier texte facilite le débugage

On retrouve donc le texte partout :

  • Dans les scripts
  • Les fichiers de configuration
  • Des formats de données d'application
  • Dans les protocoles réseau de haut niveau
  • La sortie d'informations se vos programmes

On ne le retrouve pas dans les cas où l'espace ou le temps de parsing sont primordiaux, par exemple dans les formats d'image ou de son.

Et la tendance va en s'accentuant puisqu'on utilise de plus en plus un format texte structuré un peu partout et à toutes les sauces : le xml.

KISS

Keep it simple, stupid !


continue reading...

Niveau :      
Résumé : table des partitions

Un disque dur est en général divisé en partitions. Je dis en général, car ce n'est pas obligatoire, une disquette ne l'est quasiment jamais.

Sur un PC, la table est en général au format DOS (nommé aussi MBR), je dis en général car ce n'est pas le seul format possible, même si c'est le plus courant.

Nous allons donc se restreindre au cas d'un disque dur partitionné au format DOS.

Premier secteur

Les informations de partitionnement se situent sur le premier secteur (512 octets) d'un disque. Mais il n'y a pas que ça. On y trouve des nombres magiques, et du code pour démarre la machine. La table des partitions n'est constituée que de 64 octets (de 446 à 510). On appelle ce secteur le master boot record (MBR).

mbr.png

Pour lire les données de votre MBR :

$ dd if=/dev/hda of=/tmp/mbr bs=512 count=1
$ xxd /tmp/mbr

La table contient 4 entrées de 16 octets, qui forment les fameuses 4 partitions primaires, limite originelle du nombre de partitions.

mbrtable.png


continue reading...

Niveau :      
Résumé : optiong ; unfoo ; shopt -s dotglob ; GLOBIGNORE

Ah, le grand retour du vrac, ça faisait longtemps !

Reduire la taille d'un png (sans perte) :

# il semble en général meilleur que pngcrush
$ apt-get install optipng 
# modifie le fichier inline
$ optipng fichier.png 

Décompression de n'importe quel format

# script de décompression 
$ sudo wget -O /usr/local/bin/unfoo http://obsoleet.org/code/unfoo/unfoo-1.0.6.sh
$ chmod +x /usr/local/bin/unfoo
# on cherche à décompresser toto.truc, on se fout du format
$ unfoo toto.truc

Inclure les fichiers commençant par . dans * :

# option de bash
$ shopt -s dotglob
# et hop ils apparaissent
$ echo *

Inclure les fichiers commençant par . dans * (bis) :

$ export GLOBIGNORE="."
$ echo *

Obtenir la taille d'un périphérique de bloc (comme un disque) :

$ blockdev --getsize64 /dev/sda1

Raccourci pour connaître l'heure actuelle chez votre correspondant à l'autre bout de la planète :

$ alias pdate="TZ='Pacific/Noumea' date"

Niveau :      
Résumé : SSE

Aujourd'hui l'avenir (et un peu le passé aussi). Vous souvenez-vous des cray ? Ces machines surpuissantes qui avaient au moins la puissance de calcul d'une TI92. Comment faisaient-ils pour avoir une telle puissance ? Il faisaient des calculs identiques en parallèle et multipliaient ainsi par n le nombre d'opérations. C'est ce qu'on appelle une architecture vectorielle.

Intel dans sa grande bonté a commencé à mettre en place une telle architecture dans ses processeurs. Tout d'abord avec les instructions MMX. Ces instructions utilisent les registres servant au calcul en virgule flottante (quelques transistors de gagnés), lesquels font 64 bits. On peut ainsi exécuter des instructions identiques simultanément sur 4 fois 1 octets ou sur 2 fois 2 octets. Ce qui est bien, mais pas top.

Le SSE est une amélioration du concept. Tout d'abord on utilise de nouveaux registres (ce qui libère les calculs en virgule flottante) et on leur donne une taille de 128bits. Du coup on peut manipuler deux fois plus d'entiers et cela devient intéressant pour les flottants. On peut caser 4 flottants simple précision et 2 flottants double précision dans 128 bits. Le SSE s'arrête aux 4 flottants et le SSE2 ajoute quasiment toutes les autres combinaisons possibles (flottants et entiers).

Version normale

Comme nous sommes joueurs, nous allons jouer à améliorer notre code de calcul de Mandelbrot. Mais cette fois, nous allons le laisser tourner sous linux. Comme ne sommes plus dans notre monde, mais sur un vrai système, nous allons devoir faire quelques modifications. Nous allons continuer à écrire directement en mémoire, donc on garde nos fonctions d'écriture de pixels, mais cette fois dans une mémoire allouée avec malloc. Ajoutons le support de l'écriture d'un des format d'image les plus simples, le BMP, pour stocker notre image dans un fichier et pouvoir admirer le résultat. Pour cela on prend la première documentation venue.

/* Ecriture de l'image dans un fichier bitmap (on écrit l'en-tête kivabien puis les données) */
void writebitmap(char* filename, char*bitmap, int width, int height);

Et voilà, cela nous donne une première version du code quasiment identique à la précédente et donc non optimisée pour le SSE (disponible à la fin de l'article).


continue reading...