Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archives pour décembre, 2008

Niveau : Star Star Empty Empty Empty
Résumé : .vimrc

Le retour du Jedi ! Les vacances sont finites, il est temps de de reprendre le dur cheminement dans le monde libre.

Après le vif succès du bashrc collaboratif, je vous propose de participer à un vimrc collaboratif. Le principe est le même, j'amorce le contenu d'un vimrc avec plein de petites choses utiles pour tous les jours, et vous complétez par des commentaires. Ceux-ci seront réintégrés avec votre nom dans l'article au fur et à mesure.

Attention, un guillemet double commence un commentaire :

" Plein de défauts bien pratiques (à garder en début de fichier)
set nocompatible

" Coloration syntaxique, indispensable pour ne pas se perdre dans les longs fichiers
syntax on

" Le complément du précédent, devine tout seul la couleur du fond (clair sur foncé ou le contraire)
set background&

"Détection du type de fichier pour l'indentation
if has("autocmd")
  filetype indent on
endif

" Récupération de la position du curseur entre 2 ouvertures de fichiers
" Parfois ce n'est pas ce qu'on veut ...
if has("autocmd")
  au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$")
    \| exe "normal g'\"" | endif
endif

" SI c'est pas déjà fait, affiche la position du curseur
set ruler

" Recherche en minuscule -> indépendante de la casse, une majuscule -> stricte
set smartcase

" Ne jamais respecter la casse (attention totalement indépendant du précédent mais de priorité plus faible)
set ignorecase

" Déplacer le curseur quand on écrit un (){}[] (attention il ne s'agit pas du highlight
"set showmatch

" Affiche le nombre de lignes sélectionnées en mode visuel ou la touche/commande qu'on vient de taper en mode commande
set showcmd

" Déplace le curseur au fur et a mesure qu'on tape une recherche, pas toujours pratique, j'ai abandonné
"set incsearch

" Utilise la souris pour les terminaux qui le peuvent (tous ?)
" pratique si on est habitué à coller sous la souris et pas sous le curseur, attention fonctionnement inhabituel
"set mouse=a

" A utiliser en live, paste désactive l'indentation automatique (entre autre) et nopaste le contraire
set nopaste

" Indiquer le nombre de modification lorsqu'il y en a plus de 0 suite à une commande
set report=0

" Met en évidence TOUS les résultats d'une recherche, A consommer avec modération
set hlsearch

" Crée des fichiers ~ un peu partout ...
set backup

" La ruse de sioux pour ne pas qu'ils soient partout (à vous de faire le mkdir)
" En général n'édite pas 2 fichiers de même noms fréquemment dans des répertoires différents, sinon évitez
" -> voir by eric plus bas

" Laisse les lignes déborder de l'écran si besoin
set nowrap

" En live pour quand vous écrivez anglais (le fr est à trouver dans les méandres du net)
"set spell


" Spécial développeurs
"
" Indispensable pour ne pas tout casser avec ce qui va suivre
set preserveindent
" indentation automatique
"set autoindent
" Largeur de l'autoindentation
set shiftwidth=4
" Arrondit la valeur de l'indentation
set shiftround
" Largeur du caractère tab
set tabstop=4
" Largeur de l'indentation de la touche tab
set softtabstop=4
" Remplace les tab par des expaces
"set expandtab

" by acieroid
" -----------
" Pour highlighter la ligne courante (pour mieux se repérer) en bleu :
set cursorline
highlight CursorLine ctermbg=blue

" Pour activer les numéros de lignes dans la marge :
set number

" by eric
" -----------
" Utilise shiftwidth à la place de tabstop en début de ligne (et backspace supprime d'un coup si ce sont des espaces)
set smarttab

" sauvegarder les fichier ~ dans ~/.vim/backup avec crréation du répertoire si celui-ci n'existe pas
if filewritable(expand("~/.vim/backup")) == 2
  set backupdir=$HOME/.vim/backup
else
  if has("unix") || has("win32unix")
    call system("mkdir $HOME/.vim/backup -p")
    set backupdir=$HOME/.vim/backup
  endif
endif

" donner des droits d'exécution si le fichier commence par #! et contient /bin/ dans son chemin
function ModeChange()
  if getline(1) =~ "^#!"
    if getline(1) =~ "/bin/"
      silent !chmod a+x <afile>
    endif
  endif
endfunction

au BufWritePost * call ModeChange()

" by anonyme
" -----------
" autoindent n'est spécifique à aucun langage et fonctionne en général moins bien
set noautoindent
filetype plugin indent on
filetype indent on

" by gnuk
" -----------
" On peut passer rapidement du mode paste au mode nopaste avec un raccourcis,
" builtin sur les versions récentes de vim >= 7, sinon il faudrait créer une fonction :
set pastetoggle=<F5>

" Toujours laisser des lignes visibles (içi 3) au dessus/en dessous du curseur quand on
" atteint le début ou la fin de l'écran :
set scrolloff=3

" Afficher en permanence la barre d'état (en plus de la barre de commande) :
set laststatus=2

" Format de la barre d'état (tronquée au début, fichier, flags,  :
set statusline=%<%f%m\ %r\ %h\ %w%=%l,%c\ %p%%

" Permettre l'utilisation de la touche backspace dans tous les cas :
set backspace=2

" Envoyer le curseur sur la ligne suivante/précédente après usage des flèches droite/gauche en bout de ligne :
set whichwrap=<,>,[,]

" Tenter de rester toujours sur la même colonne lors de changements de lignes :
set nostartofline

" Nombre de commandes maximale dans l'historique :
set history=50

" Afficher une liste lors de complétion de commandes/fichiers :
"set wildmode=list:full

" shebang automatique lors de l'ouverture nouveau
" d'un fichier *.py, *.sh (bash), modifier l'entête selon les besoins :
:autocmd BufNewFile *.sh,*.bash 0put =\"#!/bin/bash\<nl># -*- coding: UTF8 -*-\<nl>\<nl>\"|$
:autocmd BufNewFile *.py 0put=\"#!/usr/bin/env python\"|1put=\"# -*- coding: UTF8 -*-\<nl>\<nl>\"|$

A vous les studios ...

PS: Vous pouvez aussi taper ces commandes dans l'éditeur après un ':' et l'autocomplétion fonctionne !

Niveau : Star Star Empty Empty Empty
Résumé : tar ; par2

Comme vous les savez, les disquettes risquent de perdre facilement leurs données. Les CD aussi. Basons-nous sur un article précédent qui explique comment utiliser par2 pour éviter de perdre des données.

Nous allons nous intéresser au cas pratique de l'envoi de 25Go de données par DVD. Voici les contraintes :

  • Nombreux fichiers dans de nombreux répertoires
  • Tailles inégales des fichiers
  • Taille totale supérieure à celle d'un seul support
  • On ne veut pas perdre de données pendant le transfert
  • Un seul envoi (on ne peut pas corriger les erreurs à postériori)
  • Espace disque disponible pour la copie des données à la destination

Création des DVD

Choix du système d'archive

Puisqu'on ne veut pas de perte et un seul envoi, on va utiliser par2 pour créer une grande quantité de redondance. Par2 ne fonctionne bien que pour une liste de fichiers à plat, donc nous utiliserons un système d'archive (tar, zip ar). Puis qu'il y a de la place disque sur la destination cela ne posera pas de problème.

Puisqu'il faut répartir les données sur plusieurs supports et que les données sont de tailles inégales nous utiliserons une archive découpée en morceau.

Quelle archive utiliser ?

  • tar : gère difficilement les split d'archive
  • ar : peu pratique pour ce genre de chose
  • shar : fichiers texte, grosse perte de place
  • zip : il a beaucoup de mal a splitter ses propres fichier
  • 7zip : ne gère pas les droits sur les fichier, mais pratique
  • rar : pas libre

Calcul de la taille des fichiers

Un DVD fait environ 4482Mio (base 1024). On veut faire environ 20% de redondance (voyons large). Avec une petite marge d'erreur cela nous donne 4482/1.21 = 3700Mio par archive (soit 3788800kio pour tar). Quantité qu'on complétera par de la redondance part2 pour faire un DVD complet.

Génération des archives de chaque dvd

Utilisons tar, nous apprendrons quelque chose. Pour gérer les split avec tar, de façon un peu plus propre qu'avec tar | split, on utilise les commande de tar datant de l'époque où les sauvegardes se faisaient toutes sur cassette.

Le manuel nous renseigne sur tout ce qu'il faut :

  • Option -M pour activer le découpage sur plusieurs cassettes virtuelles (volumes)
  • Option -F pour faire un script de changement de volume
  • Option -L pour donner une taille limite aux volumes

Ce qui nous donne la commande tar suivante :

$ export FILE=test.tar
$ tar cM --volno-file $FILE.v -F 'd=dvd$(cat $FILE.v); mkdir $d; mv $FILE $d' -L 3788800 -f $FILE fichiers/de/sauvegarde
$ d=dvd$(cat $FILE.v); mkdir $d; mv $FILE $d

Pour la petite explication, on factorise le nom du fichier pour éviter les embêtements, puis :

  • -f $FILE : le volume virtuel en cours s'appelle toujours $FILE
  • --volno-file $FILE.v on : sauvegarde le numéro du tar en cours pour gérer les volumes
  • -F 'd=dvd$(cat test.tar.v); mkdir $d; mv $FILE $d' : à chaque changement de volume on déplace le volume en cours dans $FILE.<numéro>
  • d=dvd$(cat test.tar.v); mkdir $d; mv $FILE $d : on renomme correctement le dernier volume

On se retrouve donc avec N répertoires nommés dvd1 ... dvdN contenant chacun un fichier nommé $FILE

Attention, si vous voulez ajouter de la compression, c'est ici qu'il faut le faire car tar ne sait pas gérer la compression sur des archives splittées.

Génération de la redondance

La redondance se fait simplement avec par2 :

# 20% de redondance pour chaque fichier tar
$ for i in dvd*; do cd $i; par2 c -r20 $FILE; cd .. ; done

Et voilà, chaque répertoire contient avec chaque archive un certain nombre de fichiers par2 assurant la redondance des données. On peut alors graver les N DVD avec notre outil de gravure favori.

Lecture des DVD

Sans erreur de lecture

On essaie d'abord une lecture en espérant qu'il n'y ait pas d'erreur :

$ cd /destination
$ tar xM --ignore-failed-read --no-same-owner -f /media/cdrom/test.tar

A chaque fin d'archive, tar demandera de changer de volume, changer de disque puis valider.

Avec erreurs

S'il y a des erreurs de lecture, nous avons tous les outils de récupération nécessaire. On va extraire tous les DVD un par un, mais rien n'empêche de laisser sur DVD les fichiers qui sont encore lisibles.

On se base sur un article précédent sur la récupération avec ddrescue.

Si le DVD est montable on évite de perdre de la place (X étant le No du dvd) :

$ mkdir /srv/tmp/dvdX
$ for i in /media/cdrom/*; do ddrescue $i /srv/tmp/dvdX/$i; done

Sinon on récupère une image iso :

$ ddrescue /dev/hdc /srv/tmp/dvd
$ mkdir /srv/tmp/dvddir
$ mount -o loop /srv/tmp/dvd /srv/tmp/dvddir
$ cp -r /srv/tmp/dvddir/* /srv/tmp/dvdX

Et on répare le contenu du dvd :

$ cd /srv/tmp/dvdX
$ par2 r fichier.tar.par2

Reste à restaurer le contenu des archives :

$ cd /destination
$ tar xM --ignore-failed-read --no-same-owner -f /srv/tmp/dvdX/test.tar

Et même topo que précédemment pour le passage au volume précédent.

Note

C'est bien joli, mais on aurait pu faire un peu mieux (et un peu plus dur). Si un DVD est abîmé, il est probable que les données de récupération soient aussi abîmée que l'archive sur ce dvd. Pour bien faire, on devrait donc écrire les données de redondance sur un DVD différent de celui contenant l'archive correspondante.

Si quelqu'un avait le temps et le courage de mettre tout ça dans un script, ça serait bien sympa.

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

Quelques trucs et astuces de perlistes en vrac. Pour des vrais astuces de pro régulières, n'hésitez pas à visiter le site des moines de perl.

Initialiser un tableau de chaînes sans avec une syntaxe légère, très lisible quand on n'a que des mots, le séparateur étant les caractères blancs, incluant le retour à la ligne :

@tableau = qw( mot1 mot2 mot3 );

Passer du mode script de quelques lignes au mode développement long. Cela vous oblige à déclarer et initialiser toutes vos variables entre autre :

use strict;

Le debug facile :

use Data::Dumper;
# variable peut être n'importe quoi, toutes les sous-sous parties sont écrites :
print Dumper($variable,\@variable);
print Dumper(\%variable);

L'aide en ligne facile, ça fait tout de suite classe dans un script (format) :

use Pod::Usage;
# imprime le contenu de SYNOPSIS et termine le programme avec un code d'erreur 1
pod2usage(1);
# attention, pod est chatouilleux sur les retours à la ligne avant et après les =

=head1 SYNOPSIS

commande  [-o|--option=<valeur>]

=cut

La page de manuel facile (pas seulement le SYNOPSIS comme précédemment) :

# où fichier.pl est le code précédent
$ pod2man fichier.pl > fichier.1
$ man ./fichier.1

Et le dernier pour la route, le parsing d'options facile, très classe, surtout en combinaison avec pod2usage (format) :

use Getopt::Long;
my $options = {
        option => 'defaut'
};
GetOptions( $options, qw(
        option|o=s
));

Niveau : Star Star Empty Empty Empty
Résumé : !(*.gz) ; grub e ; sort rev ; diff -y ; diff <() ; man2html

Lister tous les fichiers de /var/log/apache2 sauf les fichiers compressés (bash) :

$ ls /var/log/ntpstats/!(*.gz)

Arrêter une machine pendant le boot grub :

e
halt

Trier un fichier par la dernière lettre de chaque ligne :

$ rev fichier | sort | rev

Diff presque lisible sur 2 colonnes (quand on n'a que ça) :

$ diff -y fichier1 fichier2

Diff distant :

$ diff fichier1 <(ssh -n "cat fichier2")

Pour lire les manuels dans firefox :

# À faire une fois
$ apt-get install man2html

# À mettre dans bashrc
$ mkfifo /tmp/manfifo
$ htman() { (man2html $(man -w $1) | sed -n '/<!DOCTYPE HTML/,//p' > /tmp/manfifo &) &&  firefox /tmp/manfifo; }

# Et on lit le man de grub
$ htman grub

Éditer

déc 3

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

Un autre petit voyage dans le passé nous amène à regarder l'un des tout premiers éditeurs de texte. Écrit à une époque ou les terminaux étaient constitué d'un clavier et d'un imprimante, ed est le seul, l'unique éditeur standard.

Dans la droite ligne des produits unix, ed a un nom de 2 lettres, fait une chose et le fait bien. Il est minimaliste, mais plein de fonctionnalités. Les habitués de vi et de sed ne seront pas dépaysés puisque ceux-ci sont les enfants légitimes de ed.

Une fois lancé, ed prend les commandes une par une, sur une ligne, et imprime une réponse qu'il y a lieu. C'est tout ! Reste à connaître les commandes. Ed comprend les commentaires et dispose de commandes d'une lettre a pour append, i pour insert, p pour print ... Bien qu'il ne se voit pas, ed dispose d'un curseur interne lui indiquant où il se trouve dans un fichier, celui-ci étant positionné à la fin du fichier au début de la session.

$ ed test.txt
# on ajoute une ligne à la fin du fichier (à la vi)
# l'entrée texte se termine par un point seul sur une ligne (ou ctrl-d)
a
Ligne de test
Ligne tout court
.
#on imprime tout (% à la vi, p à la sed)
%p
# on change la première ligne
1c
Ligne de retest
.
# modification à la sed
1s/Ligne/Droite/
# on sauvegarde
w
# on quitte
q

Une session d'édition est finalement très simple, surtout quand on connaît vi. Mais Pourquoi parler des ancêtres s'ils ne servent plus ? Tout simplement parce qu'il est installé partout, sur toutes vos machines. Et il se peut que certains scripts soient écrits en ed, même s'il ne fait rien qu'un bon sed -i ne puisse faire.

Niveau : Star Star Star Empty Empty
Résumé : write ; mesg ; wall ; talk

Une petite explication sur une commande du passé. A l'époque où la messagerie instantanée n'était pas encore née, où l'irc n'était qu'une vague idée, beaucoup de gens utilisaient déjà des unix. Généralement sur de gros système d'université où on trouvaient de très nombreux comptes et donc beaucoup de personnes connectées simultanément.

Write

On a alors trouvé une grande utilité à un petit utilitaire nommé write. Le concept est très simple, il permet d'écrire un message à une autre personne personne connectée à la même machine.

$ write peck
Coucou peck !
<ctrl-d>

Le système de communication est très basique, le message est directement écrit sur le terminal de la personne connectée. Comme cela peut devenir très gênant de se retrouver avec un message en plein millieu de son écran, il est possible d'interdire à un autre utilisateur de vous écrire :

# y pour réactiver
$ mesg n

Bien sur la personne peut être connectée sur plusieurs terminaux. Il est alors possible de choisir un terminal en particulier, la commande who peut vous aider à savoir qui est connecté à quel terminal :

$ who
$ write peck pts/3

La messagerie instantanée et l'irc, et la raréfaction de la ligne de commande on rendu cette communication un peu rare, voire inutile. Mais il reste une version de cette commande encore régulièrement utilisée. Wall permet d'écrire à tous les utilisateurs en même temps. Mieux, et tout comme pour write, vous pouvez même écrire aux utilisateurs qui ont désactivé la fonctionnalité si vous êtes root. Ceci sert principalement à avertir les utilisateur d'un évènement imminent sur le système :

$ wall
Attention chérie ça va couper !
<ctrl-d>

C'est même intégré à la commande shutdown.

Talk

Basé sur ce principe, et sur le fait que les utilisateurs pouvaient être sur des machines différentes, le système de conversation talk a été développé. Il nécessite cette fois un démon (talkd) qui se lance à travers inetd. Une fois installé, votre configuration inetd doit contenir ceci :

talk            dgram   udp     wait    nobody.tty      /usr/sbin/in.talkd      in.talkd

Je vous laisse deviner l'équivalent xinetd.

Une fois le démon lancé, il est possible de s'y connecter à distance avec le client talk pour parler avec un utilisateur local.

# talkd doit être en écoute sur localhost
$ talk peck@localhost

A ce moment l'utilisateur distant reçoit un message lui expliquant la commande à taper (quasiment la même) pour établir la conversation avec l'utilisateur qui le demande. On se retrouve alors avec un écran découpé en 2, chaque utilisateur ayant la moitié de l'écran pour son propre texte.

Histoire

On peut dire que ces outils appartiennent maintenant à l'histoire, mais il se peut que vous ayez encore occasionnellement besoin de write ou de wall pour un message urgent à une personne que vous savez être connecté à une machine à laquelle vous avez accès.