Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: Savoir-faire

Niveau : Star Star Empty Empty Empty
Résumé : cd && git init ; cd /etc && git init

Maintenant que vous avez étudié git, voyons à quoi il peut servir.

Configuration

Git peut, entre autre, fonctionner en local, comme RCS. Git est plus intéressant que d'autres outils comme svn pour plusieurs raison :

  • Il stocke tout en local à la racine du répertoire de travail
  • Il n'éparpille pas de fichiers un peu partout
  • Il prend 2 à 3 fois moins de place que svn pour des petits fichiers comme les fichiers de configuration
  • Il est un ordre de grandeur plus rapide que svn (ce qui importe peu pour /etc)

Notez que mercurial répond aussi à ces besoins.

Git est donc parfaitement adapté à votre configuration qui se trouve dans /etc :

# En root
$ cd /etc
$ git init

J'ai commencé par faire un "git add *" mais en pratique ce n'est pas une très bonne idée car on récupère tout et n'importe quoi et à moins de ne pas avoir de backup, ce n'est pas très utile. En effet cela entre en conflit avec les gestionnaires de paquet et gestionnaire s de configuration et c'est assez gênant lors des migrations. Une bonne utilisation est plutôt de faire un "git add" uniquement pour les logiciels dont on modifie la configuration. Ainsi, vous avez dans votre dépôt toutes vos modifications et uniquement vos modifications. Cela nécessite de s'imposer de faire les "git add" mais c'est plus simple.

D'autre part, rien ne vous empêche d'avoir un cron de commit automatique pour rattraper les cas où vous oubliez de le faire.

# Autocommit une fois par semaine, s'il n'y a rien à commiter, il ne fera rien
0 0 * * 1 cd /etc && git commit -a -m "Autocommit by cron"

Le jour où vous avez un problème de configuration :

# On cherche ce qui a changé depuis le dernier commit (fonctionnel ?)
$ git diff
# On cherche quand ça a changé avant
$ git log
# On cherche ce qui a changé avant
$ git diff ee9eac2a4deb43e7c73b50444fcb7269f172fb69

Ma configuration

Mieux, j'utilise maintenant git pour mon home :

$ cd 
$ git init

Pour le coup, on ne met vraiment que ce qu'on modifie, au coup par coup. Pour savoir quoi y mettre, commencez par lister tout ce qui commence par un point :

$ ls -ad .*

A vous de savoir ce que vous voulez y mettre sachant que ça sera transféré sur toutes vos machines. Exemples :

  • .bashrc et les .bash_*
  • .irssi
  • .vimrc
  • .ssh
  • .gnupg

Et du coup, il devient facile de se "téléporter". Dès que j'obtiens un compte sur une nouvelle machine, j'y emporte toute ma configuration. C'est assez simple (avec toutes les options) :

# Avec un git récent et une connexion bidirectionnelle
$ ssh peck@machine2.net
$ git clone ssh://peck@machine1.net/~peck/.git .

# Si la communication retour ne fonctionne pas directement
$ ssh -R 1022:localhost:22 peck@machine2.net
$ git clone ssh://peck@machine1.net:1022/~peck/.git .

# Si git se plaint de ne pouvoir créer le répertoire de destination
$ ssh peck@machine2.net
$ git clone ssh://peck@machine1.net/~peck/.git temporary
$ mv temporary/* .
$ rmdir temporary

De par le côté décentralisé de git, vous pouvez faire les modification où bon vous semble et les propager au fur et à mesure de votre usage. Voyons cela !

Ne pas oublier de de commiter

Pour les gérer les oublis, Vous avez le choix entre un autocommit régulier (voir plus haut) et un warning automatique à chaque connexion

# dans mon .bashrc
$ git status | grep modified
Vérifier les mises à jour à chaque connexion

A chaque nouvelle connexion faites un git pull, cela vous mettra à jour les données en provenance de la machine parente. Vous avez ainsi une synchronisation quasi automatique de vos répertoires personnels entre vos comptes.

# je le mets dans mon .bashrc mais c'est assez lourd si vous n'avez pas de clé ssh
$ git pull
Pousser une mise à jour vers le parent

Lorsque vous faites une modification sur un machine qui n'est pas la source (celle pour laquelle vous n'avez pas fait de git clone), il est appréciable de faire un git push pour propager les choses dans l'autre sens. Un inconvénient toutefois, c'est un lourd difficile à faire. Le plus simple est de récupérer les données depuis la source, mais ce n'est pas toujours facile à faire, cela peut nécessiter plusieurs tunnels.

# Sur la machine du changement 
$ git commit -a
# Sur la source
$ git pull ssh://peck@machine1.net/home/peck/.git

Niveau : Star Star Star Empty Empty
Résumé : ps ; top ; htop ; atop ;

Suite à un article sur les processus, j'ai trouvé une excellente série d'article vous permettant de découvrir le fonctionnement interne du noyau sur les processus et la mémoire :

Maintenant, essayons de résumer la gestion des processus d'un point de vue utilisateur et développeur.

Naissance, vie et mort d'un processus

Un processus est créé lorsque l'appel système fork est appelé et seulement dans ce cas. Les autres méthodes possibles se basent toutes sur fork (et clone, mais il ne faut pas le dire). Fork ne fait qu'une chose (et il le fait bien), il duplique un processus existant, entièrement, à l'identique, y compris ses droits.

Ensuite, durant sa vie un processus peut être modifié de nombreuses façons :

  • Changement d'utilisateur
  • Changement de code
  • Changement de père
  • Changement de priorité
  • etc.

Enfin un processus meurt dans 2 cas :

  • Il se termine tout seul comme un grand (appel système exit)
  • Il reçoit un signal qui lui est fatal

Informations sur un processus

Informations générales

Pour récupérer des informations sur un processus vous disposez de plusieurs commandes. Ces commandes ou toutes pour source /proc/<pid> qui est un répertoire virtuel peuplé directement par le noyau.

Les commandes les plus courantes sont :

  • ps : liste des processus et de leurs caractéristiques
  • htop : liste dynamique des processus et de ce qu'ils consomment
  • pgrep : récupération d'une liste de processus par expression régulière
  • pidof : récupération du pid d'un processus recherché
  • fuser : informations sur les file descriptor d'un processus
  • lsof : idem
  • pmap : afficher le mapping mémoire d'un processus
Données sur l'activité

Un processus a une activité somme toute limitée, c'est pourquoi il est parfaitement faisable de tout tracer. Le plus évident est de tracer les appels système, mais cela ne révèle que ses interactions avec le reste du monde. Il est aussi possible de tracer les appels de fonctions voire chacune des instructions.

  • strace : liste les appels système du processus
  • ltrace : liste les appels de fonction de bibliothèques dynamiques (.so) du processus
  • pstack : affiche la pile d'appel du processus
  • gdb : avec gdb on peut tout savoir et même modifier l'action d'un processus. gdb utilise l'appel système ptrace pour cela.

Agir sur un processus

Les actions sur un processus peuvent être effectuées par plusieurs entités :

  • Le processus lui -même
  • Le processus père du processus
  • Un autre processus ayant les droits pour effectuer une action (c'est-à-dire même propriétaire ou root ... en l'absence de patch sur le noyau)

Les actions qu'on peut effectuer sur un processus sont toutes liées à un appel système. En général il existe une commande shell fournissant une fonctionnalité équivalente.

Envoi d'un signal

Les signaux permettent de communiquer de façon basique avec un processus. Il peuvent être envoyé par un autre processus ou par le noyau. man 1 kill vous indique la liste des signaux et l'action par défaut associée pour les processus qui ne les surchargent pas.

Pour envoyer un signal à un processus il existe plusieurs commandes (qui utilisent toutes l'appel système kill) :

  • kill : envoyer un signal à un processus connaissant son pid
  • killall : envoie un signal à tous les processus portant un certain nom
  • pkill : envoie un signal aux processus matchant une expression régulière
  • ctrl-z : envoie le signal STOP au processus en avant plan du shell en cours
  • fg, bg : envoie le signal CONT à un processus stoppé du shell en cours
Répartir les tâches

Les processus peuvent être plus ou moins consommateurs de ressource processeur. La partie du noyau nommée ordonnanceur (scheduler) s'occupe d'allouer ces ressources aux différents processus.

Pour influencer l'activité de l'ordonnanceur, il existe plusieurs méthodes. Tout d'abord chaque processus dispose d'une priorité, le niveau de nice. Pour altérer son propre niveau, il y a l'appel système nice qui a donné la commande nice. Pour altérer celui d'un autre processus il y a l'appel système setpriority qui a donné la commande renice.

L'ordonnanceur a la charge de répartir l'activité de plusieurs processus, de plus en plus souvent entre plusieurs processeurs. Il est possible d'influencer la répartition des processus entre processeurs avec la commande taskset (utilisant l'appel système sched_setaffinity). Cette commande permet de limiter un processus à un ou plusieurs processeurs donnés.

Il existe aussi avec CFS, un moyen de contrôler finement le temps alloué à chaque processus à travers /sys/kernel/uids ou à travers les cgroups (voir Documentation/scheduler/sched-design-CFS.txt).

De plus il existe dans le noyau un deuxième ordonnanceur qui, cette fois, organise les tâches d'accès au disque. Si c'est le CFQ qui a été choisi (car il est modifiable), il est possible de l'influencer. Le grand intérêt de ceci est de limiter les processus qui pourraient phagocyter les autres en faisant énormément d'accès disque (pensez aux backups). L'appel système ioprio_set est implémenté dans la commande ionice pour gérer cette fonctionnalité. Lisez Documentation/block/ioprio.txt pour plus de détails.

Gestion des droits

Il n'est pas possible de changer les droits d'un processus de l'extérieur. Seul lui-même en est capable. Mais le mécanisme standard d'héritage lors du fork et de changement de droits lors de l'exec permet de faire tout ce qu'on veut.

Il n'existe qu'un seul cas où les droits peuvent être augmentés (en supposant l'absence de patch de sécurité spécifique) : lancer la commande exec sur un fichier disposant du bit suid (et éventuellement de capabilities).

Ensuite pour réduire ses droits, le processus peut utiliser :

  • L'appel système chroot qui a donné la commande chroot
  • L'appel système setXXuid qui est utilisé dans pam (commande login par exemple)
  • Les capabilities à travers l'appel système setcap qui permet de limiter la liste des appels systèmes disponibles pour un processus (ceci est une option du noyau)
Devenir indépendant

Un processus reçoit des signaux mortels lorsque son tty est coupé. C'est pourquoi un processus peut vouloir obtenir son indépendance.

Il appelle alors l'appel système setsid qui le détache de son terminal. De plus il crée un nouveau groupe de processus pour lui et ses fils, ce qui en pratique le détache de son père (lequel ne pourra donc plus le tuer lorsqu'il mourra).

La commande setsid fait la même chose en ligne de commande.

Limitations

Il est possible d'imposer des limitations à un processus ainsi qu'à ses fils, il existe un appel système pour cela nommée setrlimit. Bash propose une implémentation en ligne de commande pour cet appel nommée ulimit.

Les limitations incluent des limitations en nombre de fichiers ouverts, en consommation CPU, en occupation mémoire ... vous trouverez les détails dans le manuel de bash à la commande ulimit.

IPC et mémoire partagée

Une ancienne méthode chamanique utilisée pour communiquer entre processus est constituée des IPC (inter process communication). Les ipc permettent à des processus de :

  • s'envoyer des messages (appels système msgXXX)
  • poser des sémaphores, une technique de lock pour l'accès à des données (appels systèmes semXXX)
  • partager de la mémoire (appels système shmXXX)

Ces 3 catégories de méthodes génèrent des données qui sont indépendantes des processus de par le fait qu'elle sont destinées à d'autres processus. C'est pourquoi lorsqu'un processus utilisant des ipc plante, il laisse des traces dans le système. Ces traces consomment de la mémoire inutilement et parfois bloquent d'autres processus.

C'est pourquoi les commandes ipcs et ipcrm permettent de manipuler ces données de façon extérieures. Pensez à lire le manuel, c'est très court et vous pourrez en profiter pour monitorer les données en question.

Communication avec le processus

Enfin, un processus est isolé et communique avec le reste du monde de très peu de façons différentes :

  • avec des file descriptor (réseau, fichier, pipe, tty, device ...)
  • à travers la mémoire partagée et les IPC
  • avec des signaux
  • par la ligne de commande (en lecture seule)
  • et avec quelques appels système ayant une action sur le système lui-même

PKI

mar 26

Niveau : Star Star Star Empty Empty
Résumé : PKI ; IGC

Une PKI (Public Key Infrastructure), en français IGC (Infrastructure de Gestion des Clés) est un système permettant de gérer des clés publiques. Il s'agit en général de gérer des certificats x509. Elle établit un réseau de confiance entre utilisateurs, lequel passe nécessairement par l'autorité de certification.

Ces certificats peuvent servir selon leur contenu à :

Disposer d'une PKI signifie qu'on est capable de créer, pour chacun de ses utilisateurs, des certificats qui nous permettront par la suite de lui faire confiance. Pour cela une PKI offre plusieurs services :

  • Un service d'enregistrement qui vérifie l'identité des "utilisateurs"
  • Un service de signature de demande de certificats
  • Un service de renouvellement de certificats
  • Un service de publication des certificats
  • Un service de révocation des certificats
  • Un service de publication des révocations
  • Parfois un service de création de clés

Ces fonctionnalités sont généralement regroupées dans des entités séparées pour des raisons de sécurité. En effet, une PKI une fois en place devient rapidement un élément critique puisqu'elle permet de se faire passer pour une entité digne de confiance (pensez social engineering mais sans le social) . C'est pourquoi un certain nombre de fonctionnalités peuvent être installés dans un équipement dédié (un HSM, hardware security module). Du coté utilisateur, on peut faire pareil, sauf qu'on appel cet appareil dédié une carte à puce.

Mettre en place une PKI est une chose assez lourde. Mais elle devient intéressante à partir du moment où on se retrouve à gérer un grand nombre de certificats (beaucoup de serveurs ou beaucoup d'utilisateurs). Vous n'avez pas envie d'installer une PKI pour vous authentifier sur un seul serveur. Mais si vous avez 200 000 employés et que vous voulez que tout le monde signe ses mail en x509, il est temps d'en installer une.

Je voudrais attirer votre attention sur le fait qu'il ne s'agit pas seulement de créer des certificats et de les signer. La confiance se fait sur toute une chaîne, et il faut pouvoir garantir que l'autorité n'a pas été compromise (AC séparée). Il faut pouvoir garantir cette confiance dans le temps (renouvellement), il faut pouvoir se prémunir des erreurs, des vols ou des changements d'organisation (révocation). C'est pourquoi il est nécessaire de prendre son temps avant de l'installer pour bien comprendre le fonctionnement de chaque élément.

Il existe plusieurs PKI open source dont EJBCA ou NewPKI. Je parlerai d'OpenSSL, la PKI du pauvre, dans mes prochains articles. Principalement pour pouvoir mettre les mains dans le cambouis, ne pensez pas à l'utiliser tel quel comme PKI.

Niveau : Star Empty Empty Empty Empty
Résumé : perl -pe 's///'

Il arrive régulièrement d'avoir à développer des expressions régulières. Si on excepte grep et sed, la plupart des outils utilisant des expressions régulières sont compatibles perl (en utilisant PCRE). C'est donc un bon point. Apprendre les expression régulières (qu'on peut considérer comme un langage à part entière) ne sera pas perdu même si on change d'outil ou de langage.

Tests

Avant de développer une expression régulière, je vous propose de vous familiariser avec le test de ces expressions. Si vous avec une ligne de commande c'est tout simple, hop un test ligne par ligne :

$ perl -pe 's/expression/########/'
données
a matcher, 
autant que vous voulez
<ctrl-d>

Mais si vous préférez un interface plus évoluée : voici un des nombreux qui permettent de tester vos expressions en direct http://myregexp.com/ et avec coloration des éléments matchés.

Syntaxe de base

Une expression régulière, c'est une chaîne de caractère qui a pour but de repérer des informations dans un texte. Elles sont en général implémentées sous forme d'automates à état finis. Cette méthode est extrêmement efficace et dans la plupart des cas il est très difficile de faire plus rapide.

Cette chaîne peut être utilisée pour chercher des informations dans un texte, mais aussi pour faire des remplacements automatisés. Perl utilise une syntaxe autour des expressions régulières pour préciser comment les utiliser. Celle-ci est souvent reprise par les utilisateurs des PCRE mais ca n'a rien d'obligatoire :

  • /expression/ : pour faire des recherches
  • s/expression/remplacement/ pour faire du recherche/remplacer
  • y/expression/remplacement/ pour faire des substitutions de caractères

y/// est un cas particulier que nous ignorerons.

Chacune de ces chaînes peut être suivie par un modificateur. Le plus utile est /i qui permet de ne pas se soucier de la casse. Exemple : /toto/i matchera ToTo. Le deuxième plus important est /g qui permet de faire le remplacement autant de fois que c'est possible et non pas seulement la première fois que l'expression matche.

Attention, hors perl, il se peut que tout ceci ne soit pas valable, mais cela ne change rien quant à la syntaxe des expressions expliquée ci après.

Syntaxe des expressions

Le principe d'une expression régulière (abrégé en regex) est de matcher des milliers de possibilités sans devoir toutes les écrire. Il ne s'agit donc (quasiment) que de "raccourcis".

Donc commençons par les non-raccourcis :

  • () : les parenthèses ont deux fonctions, grouper des éléments entre eux et mémoriser le contenu matché pour le rendre réutilisable par la suite
  • | : opérateur OU comme dans "confiture ou nutella ?"

Exemples :

^vive (la confiture|le nutella)$

Maintenant les raccourcis :

  • . : n'importe quel caractère
  • ^ $ : début et fin de chaîne
  • [abf] : a ou b ou f
  • [a-m] : a ou b ou ... ou m
  • [^a b] : tout sauf a ou espace ou b
  • \d : un chiffre
  • \w : un caractère alphanumérique
  • \W : un caractère non alphanumérique
  • \s : un caractère d'espacement
  • \S : un caractère de non-espacement
  • a? : 0 ou 1 fois a
  • b+ : 1 ou plus fois b
  • c* : 0 ou plus fois c
  • d{3} : 3 fois d
  • ...

Il y en a plein d'autres, mais avec celles-ci vous saurez vous débrouiller dans la plupart des situations.

Exemples :

# récupérer le hostname d'un nom de domaine dans $1
(\w+)(\.\w+)*
# récupérer une heure/minute/seconde en début de ligne dans $1, $2 et $3
^(\d\d):(\d\d):(\d\d)\s
# matche une ligne variable="valeur" avec ou sans guillemets et des espaces autorisés
^\s*(\w+)\s*=\s*"?(.*)"?

Après cette petite initiation sans conséquences, vous pouvez aller lire la vraie documentation fournie en manpage avec la documentation perl man perlre.

Niveau : Star Star Empty Empty Empty
Résumé :

La gestion des langues sur les unix c'est pas le paradis. Il est possible de configurer finement les choses, mais ce n'est pas des plus adapté.

Terminal

Prenons le cas d'un terminal. La gestion doit se faire en plusieurs endroits. Tout d'abord le terminal virtuel est lui-même un processus (sauf la console linux qui se configure différemment) qui peut avoir des langues différentes. Il doit en plus être configuré pour communiquer avec la même langue que le processus qu'il fait tourner. En effet cette communication n'inclut pas explicitement la langue, il faut donc qu'elle soit définie implicitement de la même façon de chaque côté.

En supposant que le terminal soit déjà lancé avec une langue donnée (disons le français). Celui-ci vous propose encore à travers son menu (mais chaque terminal est spécifique) de configurer la façon dont il communique avec le client (bash le plus souvent).
Cette configuration gère deux choses simultanément : le format des codes de caractère venant du clavier et envoyés à l'application et le format des caractères envoyés par l'application au terminal et qui seront affichés.

L'application lancée à travers ce terminal doit parler la même langue que celui-ci (à moins qu'elle ne soit graphique auquel cas on se fout de la configuration du terminal). Les applications sont configurées au travers des variables d'environnement LANG et LC_* (ce qui explique qu'à part bash, les application supportent rarement le changement de langue en cours de route. Cela explique aussi que tous les processus fils d'une application tournent avec la même localisation (gnome et les applications graphiques par exemple).

Variables

Ces variables configurent l'entrée et la sortie des applications lancées :

  • LANG définit d'un coup la langue, l'encodage et le pays utilisés par l'application c'est une valeur par défaut qui peut être surchargées par les variables suivantes.
  • LC_* sont des variables permettant de redéfinir plus finement les valeurs de LANG. Par exemple on peut choisir une langue française mais afficher les nombre avec des points à la place des virgules. Les valeurs de * sont CTYPE, NUMERIC, TIME, COLLATE, MONETARY et MESSAGES. Chacune de ces variables correspond en réalité à une fonction de la libc.
  • LC_ALL est une variable qui surcharge tous les autres LC_* d'un coup, les mettant à la même valeur.
  • LANGUAGE est une variable qui ne définit QUE la langue utilisée pour les messages (la partie codage ne sert pas), mais permet d'en spécifier plusieurs par ordre de préférence (séparées par des ':' ).

Ces variables définissent de nombreuses choses sur la base d'un pays et de sa langue. Au format <langue>_<Pays>.<codage>@<variante>

Ainsi fr_FR définit l'utilisation du français de France et donc de toutes les conventions qui vont avec et le codage et la variante par défaut.

Et fr_FR.iso-8859-15@euro définit l'utilisation du français de France avec un encodage iso et la variante euro.

A chacune de ces valeurs correspond une façon d'écrire les nombres (10.5 ou 10,5), la date (22 juin ou jun 22), les caractères (iso ou utf8) ...

Une valeur par défaut nommée C ou POSIX existe et est toujours disponible. Elle permet de formater la communication de façon standard unix (standard US quoi) :

Pour savoir quelle locale vous utilisez en ce moment :

$ locale

L'ordre de priorité est le suivant, seule la dernière valeur est prise en compte :

  • LANG
  • LC_<selon contexte>
  • LC_ALL
  • LANGUAGE (pour les messages uniquement, attention, il arrive qu'elle ne soit pas prise en compte)

Subtilités

LC_*

Explication des différentes valeurs des variables LC standard posix (exemples entres parenthèses)

  • LC_CTYPE : encodage (utf8) et manipulation (majusculisation) des caractères
  • LC_NUMERIC : format des nombres (espace tous les 3 chiffres)
  • LC_TIME : date et heure (jour/mois/an)
  • LC_COLLATE : définition de l'ordre lexicographique, par exemple pour le tri avec ls
  • LC_MONETARY : format des valeurs monétaires (€ avec 2 chiffres après la virgule)
  • LC_MESSAGES : traduction des messages (manuel en français)

Les extensions non posix, sont-elles vraiment utilisée ?

  • LC_PAPER : dimension des feuilles de papier pour l'impression (21x29.7)
  • LC_NAME : format du nom complet d'une personne (prénom puis nom)
  • LC_ADDRESS : format d'écriture d'une adresse postale
  • LC_TELEPHONE : format d'écriture du numéro de téléphone
  • LC_MEASUREMENT : format d'écriture des unités de mesure
  • LC_IDENTIFICATION : cette variable est purement informative et permet de récupérer des informations à propos de la définition des locales correspondantes comme l'auteur ou la liste des variables prises en compte

Qui fait quoi ?

LANG est généralement modifié globalement par l'administrateur système dans /etc/default/locale ou /etc/environment . C'est une sorte de valeur par défaut, parfois surchargée dans le .bashrc

Les LC_* et LANGUAGE ne devraient être modifiées que par l'utilisateur désireux de personnaliser sont environnement.

LC_ALL ne devrait être modifié que temporairement par une application qui voudrait garantir un certain fonctionnement des méthodes qu'elle utilise.

Bien sûr, il y a toujours des exceptions.

SSH

Il est préférable de configurer ssh de façon à laisser passer les variables de langage pour que l'utilisateur se sente chez lui partout.

Définition

Les locales sont définies dans des fichiers se situant dans /usr/share/i18n/locales/ sur debian. C'est ici qu'on définit par exemple qu'en France on utilise la virgule comme séparateur de décimales. C'est ici que vous pouvez ajouter une locale Klingon si cela vous tient à cœur. Et si vous modifiez une locale, appelez locale-gen car une locale ça se compile ...

Attention, cela n'inclut pas la traduction des messages qui vont plutôt se trouver dans /usr/share/locale .

Gettext

Les logiciels utilisent majoritairement la méthode gettext pour fournir une version traduite. Celle-ci se base aussi sur les variables d'environnement lorsque le programme est bien fait.

Fichiers

Attention : changer la locale de votre shell impacte vos noms de fichier. En effet, les commandes de manipulation de fichier ne font aucune manipulation de langue. Ce qui veut dire que si vous avec un terminal en ISO-8859-1 vous verrez les noms de fichier en iso, ce qui peut donner un affichage bizarre s'ils sont en réalité en UTF-8. Faites donc bien attention à synchroniser au mieux vos usages des locales pour éviter des soucis.

En cas de besoin utilisez un outil comme convmv pour convertir votre système de fichier à une norme différente.

Niveau : Star Star Empty Empty Empty
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 : Star Empty Empty Empty Empty
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 !

Une petite question se pose sur le sens de stupid. Est-ce un deuxième adjectif présent pour renforcer le simple ou un qualificatif destiné au lecteur ? Je vote pour la première solution, mais ce n'est que mon avis.

Il s'agit ici de disposer d'outils très simples. Plus c'est simple mieux c'est. Ce n'est pas que l'utilisateur soit stupide, c'est qu'il n'a aucune raison d'aller perdre du temps à comprendre le fonctionnement de quelque chose qui est fondamentalement simple. Qui dit outils simples, dit faciles à manipuler, faciles à réutiliser.

Mais on ne parle pas seulement d'usage ici. Il s'agit aussi de garder le code simple, stupide. Cela rejoint un propos sur les commentaires dans le développement. Si votre code est bien écrit, bien architecturé, simple, alors il sera aussi simple à lire, à maintenir et à débuger, pas besoin de milliers de lignes de commentaires.

Faire une chose et le faire bien

Unix a inventé le pipe '|', une méthode simpliste pour faire communiquer 2 programmes entre eux. Cette communication est unidirectionnelle et non formatée, seules des données brutes y passent. Et pourtant, à lui seul le pipe a fait beaucoup plus pour unix que n'importe qui.

Grâce au pipe et au fait que la plupart des programmes communiquent avec un format texte, il est possible de faire des programmes qui ne soient que des filtres, qui ne fassent qu'une chose sur les données qu'on leur donne, et qui le fassent bien. Il est possible de faire des choses qui n'étaient pas prévues mais qui sont rendues possibles par l'apparition d'un nouveau filtre.

Bien sûr après le pipe, on a inventé la socket qui communique dans les 2 sens, ainsi que bien d'autres moyens de communiquer d'un processus a l'autre. Mais ce ne sont que des évolutions servant à pousser toujours un peu plus loin le principe : faire une chose et le faire bien. Quel que soit ce que vous développez, arrangez-vous pour que votre logiciel sache communiquer avec les autres logiciels unix. Ainsi vous garantirez une utilisation bien plus large à votre produit que celle que vous aviez dans la tête.

Puisque les autre outils sont déjà des outils simples qui font une chose et bien, vous pouvez aussi les réutiliser et vous appuyer sur les épaules d'un géant.

Quelques ressources ici et .