Fedora-Fr - Communauté francophone Fedora - Linux

Planet de Fedora-Fr : la communauté francophone autour de la distribution Linux Fedora

A propos

Cette page est actualisée toutes les heures.

Cette page est une sélection de blogs autour de Fedora. Fedora-Fr.org décline toute responsabilité au sujet des propos tenus par les auteurs des blogs de ce planet. Leurs propos sont leur entière responsabilité.

Le contenu de ce planet appartient à leurs auteurs respectifs. Merci de consulter leur blogs pour obtenir les licences respectives.

Mot-clefs : bash

Ralonger l'historique du shell

Edouard Bourguignon

En shell, l'historique joue un rôle bien pratique en nous permettant de rappeler et/ou de retrouver d'anciennes commandes. Par défaut il ne conserve que 1000 entrées, ce qui suffit bien souvent. Mais sur des serveurs très utilisés, ou pour n'importe quelle autre raison, il est possible de changer cette valeur. Pour cela il suffit d'ajouter dans votre ~/.bashrc la ligne suivante (où de la corriger si elle existe déjà):

export HISTSIZE=3000

Cette valeur sera prise en compte au prochain login, mais pour que ce soit pris en compte immédiatement, au choix:

  • source ~/.bashrc
  • ou taper la commande export HISTSIZE=3000

Pour s'en assurer:

echo $HISTSIZE

Pour voir la taille actuelle de l'historique:

history | wc -l

J'avais déjà cité il y a quelques temps des raccourcis bien pratiques, certains utilisent l'historique.

PS: cette méthode a été testé sous bash uniquement.

Typescript to gif - convertir une capture terminal vers un gif animé

Patrice Ferlet

Comment utiliser la commande "script" et un peu de bash + imagemagick pour en faire une animation en GIF (ou pourquoi pas une vidéo par la suite)

Cette semaine, un administrateur système m'a montré une commande que je ne connaissais pas du tout... "script". Ce petit utilitaire permet d'enregistrer le flux terminal vers un fichier afin d'être relu. En grattant dans le "man" j'ai découvert deux options intéressantes, l'une d'elle permet de garder les "temps" de commande + le nombre de caractères à lire... On peut alors utiliser "scriptreplay" pour relire la session ou bien, comme moi, jouer avec et créer une animation

Prenons le temps de comprendre. Si je tape la commande:

script --timing=/tmp/timing /tmp/script

alors commence une session enregistrée dans le fichier /tmp/script.

Tapons alors des commandes, par exemple

echo "hello world"

Puis pressez CTRL+D. La session "script" s'arrête. Vous pouvez rejouer la session (qui ne va pas rejouer les commandes, mais les afficher avec les résultats de l'époque...) en utilisant "cat"

cat /tmp/script

Or... on a besoin de voir "à la replay" la commande. Soit:

scriptreplay -t /tmp/timing /tmp/script

Et là, c'est déjà plus joli. Mais voilà, pour partager une capture de ce genre en vidéo (ou en gif animé) ce format ne nous convient pas encore. On va donc réfléchir recréer une belle vidéo de tout ce beau monde.

Première option, on fait un screencast (avec ffmpeg) mais bon... la souris peut apparaître... et puis pour en faire un gif c'est pas encore ça.

Seconde option, celle qu'on va mettre en place, est de faire ceci: - relire le fichier /tmp/timing - prendre séquence par séquence le texte depuis le typescript (fichier généré par la commande script) - afficher ça dans le terminal et faire une capture du terminal avec la commande "import" - relire une fois de plus le timing et cette fois ci: lire les temps d'attente - utiliser "convert" avec l'option -delay pour mettre frame à frame les images dans le gif animé.

Voilà... bon je vais pas passer par 4 chemins, le but n'est pas de vous apprendre à faire du bash mais au moins vous parler des "soucis" que j'ai dut régler: - lire un fichier d'un certain endroit à un autre: on utilise "dd" - créer des images numérotées avec 5 chiffres pour être à l'aise: printf

Le reste coule presque de source... Voilà le script:

#!/bin/bash

TIMING=$1
SCRIPT=$2
W=$WINDOWID

rm -rf /tmp/script-replay-gifs/
mkdir /tmp/script-replay-gifs/

t=$(mktemp)
cp $SCRIPT $t

#remove first line
sed -i '1d' $t

#clear screen
clear

#read timing file one by one
curr=0
i=0
while read line
do
    #capture time and chars to read
    cols=($line)
    chars=${cols[1]}
   
    #read from current char the number of chars to read
    dd if=$t bs=1 skip=$curr count=$chars 2>/dev/null

    #convert to gif frame with a nice frame-number
    n=$(printf "%010d" $i)
    import -winow $WINDOWID /tmp/script-replay-gifs/$n.gif

    #and move to next position
    curr=$((curr+chars))
    i=$((i+1))
done <$TIMING
rm -f $t

#now, set gif with delay per frame
i=1
while read line
do
    cols=($line)
    timing=${cols[0]}
    #get next image
    file=$(ls -1 /tmp/script-replay-gifs/ | head -n $i | tail -n 1)
    timing=$(echo "$timing*100" | bc -l | awk '{print int($0)}')
    command=$command" -delay $timing /tmp/script-replay-gifs/$file"

    i=$((i+1))
done < $TIMING

convert $command /tmp/anim-notoptim.gif
convert /tmp/anim-notoptim.gif -coalesce -layers Optimize /tmp/anim.gif

rm -f /tmp/anim-notoptim.gif
rm -rf  /tmp/script-replay-gifs/

Ce script est très très lent à cause de "import" qui prend près d'une seconde par capture... de ce fait pour le moment c'est pas un modèle du genre... et en plus, vous ne pouvez pas quitter le bureau dans lequel vous être pour créer l'animation sous peine de messages d'erreur. Notez que ce n'est un qu'un petit test

Cela donne: Animation terminal

Pour le coup, j'ai quand même posé un petit coup de "gimp" pour optimiser le gif animé. Je vous laisse maître de me faire des remarques et pourquoi pas (si vous le demandez) je créerai un dépôt git quelque part pour qu'on le fasse évoluer.

Update: j'ai ajouté une opération d'optimisation de taille à la fin du script

Configurer Mutt pour gmail

Patrice Ferlet

Il est évident que nous ne sommes pas tous accrocs aux outils en mode texte (dans un terminal) mais personnellement j'y trouve mon compte: vitesse, exécution claire, lisibilité... et modularité. Je suis un Google Fan (houuu je vais m'en prendre plein la poire moi) et j'ai beaucoup de mes données sur Google: mail, documents, agenda... Voici donc comment pouvoir envoyer des mails et lire ces derniers convenablement avec Mutt, y compris l'autocompletion des contacts Gmail

La configuration ne sera pas compliqué. Il faudra juste se farcir 3 fichiers de configurations:

  • un pour mutt lui même, configuration du compte
  • un pour permettre les macros de lecture de mail en HTML
  • un fichier netrc pour permettre à goobook de fonctionner

Bref, passons en premier lieu à l'installation proprement dite des logiciels:

su -c "yum install mutt python-setuptools links"
easy_install goobook

Le première commande installe mutt et les utilitaires pytyon pour installer un paquet python, puis links, le lecteur html en console. L'autre installe goobook, un outil qui permet de récupérer un carnet d'adresse google.

Goobook est un outil python que j'ai testé après en avoir essayé plusieurs, c'est de loin le plus pratique et le plus abouti que je connaisse. Vous pouvez voir la page du projet ici: http://pypi.python.org/pypi/goobook...

Maintenant, passons à la configuration de Mutt

#fichier ~/.muttrc

#enregistre les messages envoyés et brouillons dans Gmail
set record="+[Gmail]/Messages envoyés"
set postponed="+[Gmail]/Brouillons"

#configuration du serveur
set hostname=gmail.com
my_hdr From: PRENOM NOM <USER@gmail.com>
set use_envelope_from
set envelope_from_address="USER@gmail.com"

unignore Date Message-ID In-Reply-To

set move=no
set spoolfile=imaps://imap.gmail.com:993/INBOX
set imap_user = "USER@gmail.com"
set imap_pass= "VOTRE MOT DE PASSE"
set imap_authenticators="login"
set imap_passive="no"
set folder="imaps://imap.gmail.com:993"
set imap_check_subscribed="yes"
set imap_list_subscribed="yes"

set smtp_url="smtps://USER:VOTRE MOT DE PASSE@smtp.gmail.com:465"
set ssl_starttls="yes"

set locale="fr_FR"
set date_format="%A %d %b %Y à %H:%M:%S (%Z)"
set attribution="Le %d, %n à écrit:"
set forward_format="[Fwd: %s]"
set forward_quote

mailboxes !

set pager_index_lines="7"
set pager_stop

#gérer un cache
set message_cachedir="~/.mutt_msg_cache"
set header_cache="~/.mutt_header_cache"

#force l'utilisation d'un programme exterieur pour les mails en HTML
auto_view text/html

#et ici la config pour les contacts
set query_command="goobook query '%s'"
bind editor <Tab> complete-query
macro index,pager a "<pipe-message>goobook add<return>" "add the sender address to Google contacts"

Et enfin il faut configurer les commandes pour lire les mails HTML:

#fichier ~/.mailcap
text/html;  links %s; nametemplate=%s.html
text/html;  links -dump %s; nametemplate=%s.html; copiousoutput

Bien. Reste à gérer goobook, on commence par créer un fichier:

#~/.netrc
machine google.com
    login USER@gmail.com
    password Votre Mot de passe

Voilà, testez rapidement que ça passe en tapant:

goobook reload
goobook query un_nom_au_choix

Et bien voilà, lancez maintenant la commande mutt et appréciez un peu la lecture de mail dans un terminal.

Souvenez vous de quelques racourcis:

  • Maj+D pour supprimer un ensemble de mail correspondant à un motif que vous tapez (par exemple si vous tapez microsoft, tout les mails correspondants seront marqué comme "à supprimer")
  • d pour supprimer le message sélectionné
  • m pour envoyer un message (les contacts sont auto complétés via la touche tabulation)
  • r pour répondre
  • c por changer de dossier de mail
  • / pour chercher un mail, selon le nom, le sujet...
  • $ pour valider les changements (suppressions)

Voilà, personnellement j'ai adopté mutt et j'en suis très content. Je classe et nettoie ma boite mail en 4 fois moins de temps qu'avant.

Notez que nous pourrons ensuite utiliser mcabber pour tchater avec nos contacts google :)" class="smiley on en reparlera

EDIT: j'ai supprimé la phase de création de goobookrc qui est inutile en fait...

Comment stocker dans un tableau le résultat de la command find ?

Jonathan Mercier

Bonjour, Ce billet est destiné de prime a bord à être un pense bête, mais sait on jamais si des personnes ont le même beson. Comme annoncer dans le titre le bout de code suivant permet de récupérer les informations retourner par la commande find.


  1. unset result index
  2. while IFS= read -r -u3 -d $'\0' file; do
  3. result[index++]="$file"
  4. done 3< <(find . -type f -print0)
  5. echo ${result[0]}

La première ligne permet de supprimer les éventuels déclarations de ces variables. Le bloc while permet de lire la sortie standard qui est redirigé par l'opérateur <<. Ainsi fichier après fichier découvert par la commande find la variable index est incrémenté afin de stocker le résultat à l'index suivant du tableau.

En espérant que ce petit bout de code puisse aider un jour

Signé: bioinfornatics, Jonathan MERCIER

Point de montage d'archives

Patrice Ferlet

Si comme moi vous avez besoin d'utiliser le contenu d'un tar.gz, d'un zip, ou tout autre archive et que cela vous agace de devoir le décompacter pour le modifier et le compresser par la suite pour le déplacer... ce billet va vous intéresser. Nous allons parlons ici de "archivemount", un outil sympa comme tout, utilisant "fuse", et qui va vous faire gagner un peu de temps.

Il m'arrive souvent ce genre de chose. Devoir récupérer une archive tar.gz ou tar.bz2, ou encore un zip, et devoir le décompresser pour l'utiliser avec une application (par exemple un storage pour ezPublish que je déplace pour bosser chez moi, ou la création d'une archive de release que je veux manipuler et vérifier simplement). Le fait est que l'archive est parfois lourde, et devoir ajouter des fichiers ou en supprimer, ou même en modifier est parfois un peu... suante. Gnome, KDE, proposent bien un outil de montage dans le navigateur de fichier, mais moi je suis sur Xmonad et j'aime le terminal. C'est donc le moment de vous montrer l'outil qui rend bien service "archivemount"

Sur Fedora il est dans les dépôts standard, donc un simple:

su -c "yum install archivemount"

et le tour est joué.

Alors comment ça marche tout ça ?

Imaginons une archive monarchive.tar.gz que je veux utiliser comme un répertoire. Encore une fois, les systèmes UNIX sont bien sympa en ce qui concerne la gestion de point de montage. Fuse va être utilisé avec archivemount. C'est simple comme tout:

mkdir ~/monarchive
archivemount monarchive.tar.bz ~/monarchive

Et voilà... c'est tout. dans le répertoire ~/monarchive se trouve le contenu de l'archive. Toute modification dans ce répertoire se répercute (au démontage) dans monarchive.tar.gz.

C'est donc un point de montage, simple, clair et efficace. A peu près tout fonctionne: tar (compressé ou non en gz, bz2...), xv, cdrom iso, zip... et les options de mount sont évidemment utilisables (ro, rw, nosuid...) comme avec n'importe quel point de montage.

Notez que le mode d'écriture asynchrone force donc la recompression au démontage.

Un chroot si rapide à créer

Patrice Ferlet

J'avais travaillé sur la documentation de chroot sur cette page: http://doc.fedora-fr.org/wiki/Utili... mais depuis, les choses ont changé. Febootstrap ne marche plus du tout comme avant... et j'ai trouvé une manière encore plus simple de créer une base chroot sans manipuler des fichiers de dépôts. Vous allez voir, c'est tellement simple que ça en est presque indécent.

Voilà la manière la plus facile que j'ai trouvé, par exemple pour encapluser "php-cli" dans un chroot:

cd ~
mkdir -p chroots/fedora-15-chroot
cd chroots
su -c 'yum --installroot=`pwd`/fedora-15-chroot --releasever=15 install php-cli -y'

C'est simple comme choux en fait...

Je crée un répertoire dans mon "home" (cd ~ et mkdir -p chroots/fedora-15-chroot). Ensuite je demande à yum d'installer php-cli dans le répertoire fedora-15-chroot. Comme je n'ai pas créé de fichier de dépots Fedora dans le répertoire de chroot, je spécifie simplement que je veux utiliser la version "15" de fedora. Notez que "releasever" est une contraction de "release version".

Et comme par enchantement, j'ai un chroot fonctionnel !

Là où c'est intéressant, c'est que je me passe de pas mal de configuration un peu compliqué. Il est alors facile de changer de --releasever en 16 pour tester la rawhide, ou une version inférieure...

Me reste plus qu'à voir comment fonctionne lxc (et je n'ai pas la dernière version de libvirt donc je n'ai pas encore l'accès facilité par virt-manager) et je vais pouvoir tester pas mal de choses, comme faire marcher des bases en jail, compiler des choses tordus ou voir comment péter un système sans avoir peur :)" class="smiley

Faire parler son pc

Patrice Ferlet

Ça peut paraître gadget, mais on se rend compte assez vite que la synthèse vocale sur un poste peut être intéressante dans pas mal de cas. Par exemple, j'ai tendance à compiler des applications assez lourdes, et pour être prévenu, j'aime avoir une voix qui me dit "la compilation de blender 2.58 pour cycles est terminée sans erreur"... Ou encore, me prévenir vocalement que j'ai un souci sur un serveur distant... Cela permet d'avoir une annonce clair et de ne pas avoir constamment sous les yeux un panel de tests. En gros, c'est pratique, gadget oui, mais pratique.

Alors comment faire causer notre coucou. Il existe des méthodes libres et/ou gratuites. Je vais vous montrer une procédure pas à pas qui va vous permettre d'avoir une jolie voix sur le pc (si on est pas trop regardant) et comment utiliser cela pour pas mal d'opérations. Le but est de faire simple, pratique et utile.

Première approche, espeak seul.

Espeak est un projet libre, facilement installable sur votre Fedora puisque dans les dépots officiels. Pour l'installer vous pouvez passer par l'outil d'ajout de paquets ou via une console:

su -c "yum install espeak -y"

A partir de maintenant, vous avez la commande espeak qui vous permet de faire parler le pc. Avant de vous lancer en vous disant "ça y est mais trop bien !!!" je tiens à vous prévenir: ça va pas être super beau. En effet, la voix anglaise est à peu près écoutable, par contre en Français... mon dieu. Je veux bien être indulgent, mais honnêtement là vous allez voir c'est pas super joli.

Exemple:

espeak -vfr "bonjour à toi humble utilisateur de la console"

Ça pique un peu non ?

En anglais c'est à peine mieux:

espeak  "I dude, this is better, isn't it ?"

Bref, si cela vous plait vous pouvez utiliser epseak tel quel... mais personnellement j'ai eut envie de trouver mieux. Et la solution a été "mbrola". Notre méthode va utiliser espeak et mbrola, le premier pour générer des phonèmes et l'autre pour parler.

Deuxième approche: espeak + mbrola

mbrola est un projet gratuit mais non libre. Je suis pas fan de la politique qu'ils utilisent, d'autant que le projet a l'air de sombrer doucement dans les abîmes des ligiciels qui auraient put devenir des références pour des années... Mais toujours est-il qu'à l'heure actuelle on peut encore s'en servir.

Donc, on va préparer notre installation.

su -
mkdir -p /opt/mbrola
cd /opt/mbrola
wget http://tcts.fpms.ac.be/synthesis/mbrola/bin/pclinux/mbr301h.zip
unzip mbr301h.zip
rm -f mbr301h.zip

Oui, que vous soyez sous 64bits ou 32bits, on devra utiliser la version 32bits.

mbrola a besoin de fichier de voix. On va récupéré l'une de celle qui va le mieux pour notre test:

mkdir fr4
cd fr4
wget http://tcts.fpms.ac.be/synthesis/mbrola/dba/fr4/fr4-990521.zip
unzip fr4-990521.zip
rm -f fr4-990521.zip
exit

N'oubliez pas de bien taper "exit", nous ne devons plus être "root" à partir de maintenant.

Bon, maitenant que le paquet est là... on passe au "pipe" qui permet de faire parler mbrola. Il faut savoir que espeak embarque quelques "voix" de mbrola par défaut. Donc nous allons utiliser cela pour faire causer l'ordinateur.

Bon je vous explique rapidement, on va pas trop détailler le principe

  • espeak -vmb/mb-fr2 "texte à donner" retourne une sortie qui correspond aux phonèmes au format reconnu par mbrola
  • mbrola fichier-de-voix phonèmes fichier.format: va lire l'entrèe de phonèmes et sortir un fichier au format désiré "au, wave..."

Comme nous ne voulons pas créer des fichiers sur le disque, on peut "piper" les sorties. De ce fait:

mbrola fichier_de_voix - -.au | play - 2>/dev/null

aura pour effet de récupérer les phonèmes depuis l'entrée standard et créera un fichier "au" directement envoyé à la sortie standard. "play" va alors lire cette sortie standard et nous redirigeons toutes les erreurs dans /dev/null pour ne pas polluer notre console...

Donc le pipe complet est:

espeak -vmb/mb-fr4 "Bonjour à toi humble utlisateur de la console" | /opt/mbrola/mbrola-linux-i386 /opt/mbrola/fr4/fr4 - -.au | play - 2>/dev/null

Ha oui, elle parle vite la nana hein :)" class="smiley

Et bien nous allons palier la vitesse via les options de mbrola.

  • -t 1.2 par exemple va réduire la vitesse de parole d'un ration de 1.2

Ce qui nous donne:

espeak -vmb/mb-fr4 "Bonjour à toi humble utlisateur de la console" | /opt/mbrola/mbrola-linux-i386 -t 1.2 /opt/mbrola/fr4/fr4 - -.au | play - 2>/dev/null

Mieux n'est-ce pas ?... On peut encore jouer avec quelques options, comme le "pitch" (hauteur de voix) et le volume:

  • -v 0.8 volume à 80%
  • -f 1.1 monte le pitch de 10%
espeak -vmb/mb-fr4 "Bonjour à toi humble utlisateur de la console" | /opt/mbrola/mbrola-linux-i386 -f 1.1 -v 0.8 -t 1.2 /opt/mbrola/fr4/fr4 - -.au | play - 2>/dev/null

Comme je vous le disai, c'est mieux que espeak mais on est encore loin de la beauté extême. Le souci n'est pas mbrola, mais la création des phonèmes. Car les exemples proposés par mbrola vous montre qu'on pourrait s'y tromper.

Automatisation

Bon il nous reste une chose à faire, rendre utilisable aisément cette commande. Et bien faisons ça simple:

su -
cat > /usr/local/bin/sayit<<EOF
espeak -vmb/mb-fr4 "\$@" | /opt/mbrola/mbrola-linux-i386 -f 1.1 -v 0.8 -t 1.2 /opt/mbrola/fr4/fr4 - -.au | play - 2>/dev/null
EOF
chmod +x /usr/local/bin/sayit
exit

Voilà nous avons créé une commande "sayit" qui va nous permettre de faire cela:

sayit "Que c'est bien de travailler sous linux"

Reste alors à utiliser notre commande comme je vous le disais au début de l'article. Par exemple, quand je compile un programme:

make && sayit "Compilation de Blender terminé avec succès" || sayit "Compilation de Blender avec erreurs"

Et j'en passe, vous pouvez faire un petit programme en bash qui lit des logs et vous annonce une erreur, ou encore un module XChat qui vous préviens que quelqu'un vient de vous parler.

Ce gadget est intéressant quand on est comme moi à travailler sur plusieurs machines en même temps, souvent en train de préparer du café, ou sur plusieurs taches en même temps.

Voilà, j'espère que vous avez apprécié mon explication et si vous avez des idée d'utilisations ou script, faites passer !

Jouer avec le bash pour faire un benchmark

Patrice Ferlet

Avant toutes choses, je ne suis pas un dieu du bash, loin de là. J'avais besoin de faire un petit benchmark entre node.js, php et python. Et je vous avoues que j'avais pas très envie de créer des scripts partout pour une opération "one shot"... Connaissant un peu les capacités de bash, j'ai tapé instinctivement (je vous assure) les commandes que je vais vous expliquer. Le but était à la base de créer le moins de fichiers possibles. En fait tout ce dont j'avais besoin c'était de créer les fichier de résultats de temps et de visualiser un graphique. Vous allez voir que ce que je vais vous présenter ne crée que 3 fichiers, en fait un fichier de "log" de temps d'exécution par langage. Pour le reste, c'est bash qui va s'occuper de me rendre service, ainsi que le fabuleux gnuplot.

Juste une petite parenthèse, ce billet est surtout là pour montrer à quel point le terminal de commandes est puissant si l'on se penche un peu sur l'ensemble des commandes utiles. Un peu d'entrainement permet de régler des tas de soucis, mais aussi, comme dans mon cas présenté ici, de permettre des travaux qui peuvent paraître compliqués... mais finalement réglé en quelques minutes... Encore une fois, je connais bien Bash et cela vient naturellement, mais je n'ai pas plus d'aptitude que la plupart des linuxiens sur un terminal. Ma seule performance ici est d'avoir la folie et l'amour des lignes de commandes pour ce genre de process.

Très bien, pour être précis mes benchmarks se portaient sur le calcul de 32 rangs de la suite de fibonnacci. Pour ceux qui ne la connaissent pas, je vous la présente rapidement: 0 1 1 2 3 5 8 13 etc...

En fait c'est simple, on part de 0 puis 1, ensuite il faut ajouter les deux nombres précédents pour trouver le nombre du rang "n".

  • 0 et 1 engendre: 0+1=1
  • la suite est donc 0 1 1
  • ensuite je prend les deux derniers chiffres: 1 et 1, je les additionne: 1+1=2
  • la suite devient 0 1 1 2
  • on continue de la même manière, les deux derniers chiffres de la suite étant 1 et 2: 1+2=3
  • la suite devient 0 1 1 2 3
  • et ainsi de suite, les deux derniers chiffre étant 2 et 3: 2+3=5
  • la suite devient 0 1 1 2 3 5
  • etc...

Algorithmiquement, cela peut se résoudre par une fonction itérative:

fonction fibo (n)
    si n vaut 0 ou 1 on retroune n
    sinon on retourne fibo(n-2)+fibo(n-1)

Ok, pour python, php et node (javascript) cela va se faire en 3 ou 4 lignes... et plutôt que de créer un script, je fais appel aux interpréteurs directement en ligne de commande. Par exemple pour avoir le rang 10 en PHP:

php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo(10);
'

Ça fonctionne bien.

Reste que je veux calculer tous les rangs allant de 0 à 32... et bien bash me permet de boucler:

for i in $(seq 1 32)
do
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
done

Pas mal... mais il me reste un truc à faire, chronométrer le processus... alors oui je sais, il existe la commande "time" mais elle est pas si simple à gérer en terme de sortie, moi j'ai besoin d'avoir juste le temps total, seconde et milisecondes comprises... et bien c'est simple, on va enregistrer le timestamp + les nanosecondes via la commande "date" avant puis après le processus. Il suffira de soustraire les temps pour avoir le différenciel.

Voilà comment je benchmark PHP:

for i in $(seq 1 32); do 
echo -n $i" "
_s=$(date +%s.%N)
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
'
echo $(date +%s.%N)-$_s | bc -l
unset _s
done

Je vous explique. je boucle 32 fois sur la suite de commande:

  • echo -n $i" " : pour savoir où j'en suis, j'ajoute un espace après le nombre, et j'utilise "-n" pour ne pas revenir de suite à la ligne
  • _s=$(date +%s.%N) : je place la date en timestamp (nombre de secondes depuis 1970) suivit de "." et les nanosecondes en cours
  • php -r... : on exécute le code php
  • echo $(date +%s.%N)-$_s | bc -l : j'écris l'opération "date courante avec nanoseconde" - "date enregistré avant le process" et je l'envois à "bc -l" qui va calculer ça
  • unset _s : juste pour virer la vairable $_s qui va plus nous servir.

Bon, vous avez compris, me reste plus qu'à enregistrer le résultat dans un fichier. Je vais donc dans /tmp et je crée un répertoire "bench":

mkdir /tmp/bench
cd /tmp/bench

et je fais le logs, pour PHP en premier (dieu que c'est lent...):

for i in $(seq 1 32); do 
echo -n $i" "
_s=$(date +%s.%N)
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
'
echo $(date +%s.%N)-$_s | bc -l
unset _s
done>php.log

On fait pareil pour node:


for i in $(seq 1 32)
do
echo -n $i" "; _s=$(date +%s.%N);
node <<JS
function fibo(n) {
return (n==0 || n==1 ) ? n : fibo(n-2)+fibo(n-1);
}
fibo($i);
JS
echo $(date +%s.%N)-$_s | bc -l; 
unset _s; 
done>node.log

et enfin pour python:

for i in $(seq 1 32)
do 
echo -n $i" "
_s=$(date +%s.%N); python -c '
def fibo(n):
   return n if (n==0 or n==1) else fibo(n-1)+fibo(n-2)
fibo('$i')
'
echo $(date +%s.%N)-$_s | bc -l; 
unset _s; 
done>python.log

J'ai donc là 3 fichier qui contiennent chacun des logs de temps, je vous montre celui de PHP:

$ cat php.log 
1 .036828663
2 .025703992
3 .026992606
4 .033444640
5 .035266864
6 .033452564
7 .028677243
8 .036187726
9 .035308338
10 .033860607
11 .030994306
12 .031643060
13 .030666493
14 .033131695
15 .037534009
16 .034849018
17 .036111420
18 .042433952
19 .044907994
20 .052853506
21 .068992452
22 .086515691
23 .125384399
24 .180959996
25 .279442730
26 .412510010
27 .648189657
28 1.019483322
29 1.626384710
30 2.644171263
31 4.257360111
32 6.938595991

Mon souci va être d'utiliser les 3 fichiers en même temps dans gnuplot... plutôt que de passer par 3 commandes en entrée (je vais vous montrer comment on fait dans gnuplot) je vais utiliser une commande que j'adore: paste

Cette commande est magique, elle "colle" en colonnes les fichiers les uns à coté des autres, voici ce que ça donne chez moi:

$ paste *.log
1 .065706975    1 .036828663    1 .051057606
2 .075880231    2 .025703992    2 .046552158
3 .073986169    3 .026992606    3 .046123806
4 .073072239    4 .033444640    4 .042877291
5 .070891448    5 .035266864    5 .045012469
6 .074523262    6 .033452564    6 .047550418
7 .072727132    7 .028677243    7 .042658307
8 .075226716    8 .036187726    8 .045704715
9 .069166717    9 .035308338    9 .046088504
10 .071344391   10 .033860607   10 .043567632
11 .072756556   11 .030994306   11 .043765426
12 .073284181   12 .031643060   12 .043340776
13 .072755513   13 .030666493   13 .045153174
14 .068839918   14 .033131695   14 .047908738
15 .079993544   15 .037534009   15 .050165910
16 .072923693   16 .034849018   16 .048907127
17 .074823342   17 .036111420   17 .047513241
18 .073899009   18 .042433952   18 .053685052
19 .069858333   19 .044907994   19 .048828831
20 .071467252   20 .052853506   20 .050347929
21 .073423093   21 .068992452   21 .049505150
22 .074624496   22 .086515691   22 .060360949
23 .071165563   23 .125384399   23 .068465359
24 .076328627   24 .180959996   24 .079916752
25 .076409643   25 .279442730   25 .100771059
26 .079967605   26 .412510010   26 .136666736
27 .076491429   27 .648189657   27 .198588958
28 .085810737   28 1.019483322  28 .293586222
29 .095436353   29 1.626384710  29 .434787310
30 .104759161   30 2.644171263  30 .675019713
31 .125979134   31 4.257360111  31 1.074293193
32 .155473948   32 6.938595991  32 1.705526686

S'en est presque poétique... non ? Vous avez remarqué qu'on a besoin ici des colonnes 1, 2, 4 et 6 pour avoir la valeur de 'n' et le temps d'exécution pour chaque langage. Notez aussi que les colonnes représentent les fichier dans l'ordre alphabétique du nom du fichier de log, ainsi de gauche à droite on a "node", puis "php" et enfin "python"...

Bon on passe à gnuplot, on lance la commande gnuplot et on tape ceci:

gnuplot> set title "Benchmark Fibonnacci"
gnuplot> set xlabel "n value"
gnuplot> set ylabel "time in seconds"
gnuplot> set grid
gnuplot> plot "< paste *.log" using 1:2 with line title "node", "< paste *.log" using 1:4 with line title "php",  "< paste *.log" using 1:6 with line title "python"

Je sais que j'aurais put utiliser les fichier les uns après les autres mais la commande "paste" me permet des copier/coller rapides de mes commandes sans avoir à changer le nom du fichier à chaque fois... et puis je voulais vous parler de cette commande d'abord hein !

Bref, le résultat est de cette forme: Fibonnacci benchmark gnuplot

Vous l'aurez donc compris, en maitrisant un peu le bash on peut effectuer des opérations assez poitilleuses sans pour autant à avoir à gérer un projet complet de scipts... le tout est de s'entrainer, et tout devient instinctif.

Je le répète, j'ai fait ces opérations sans me poser de questions, et comme je me suis rendu compte que ça pourrait intéresser certains... je me suis dit qu'il serait bon de montrer un peu comment je procède.

Et bien voilà, explication terminée. En espérant que ça vous ait donné envie de taper des lignes de commandes plutôt que de passer par un tableur... ;)" class="smiley

PS: désolé pour les fautes dorthographe mais j'ai du mal à les trouver ce soir... je corrigerai demain...

Rechercher une adresse MAC avec grep

Edouard Bourguignon

Pratique de pouvoir rechercher ou valider une adresse MAC avec une commande shell, et comme grep supporte très bien les expressions régulières cela est même facile à utiliser.

Pour construire notre expression régulière, il faut réfléchir sur ce que nous cherchons. Une adresse mac est toujours représentée comme suit: XX:XX:XX:XX:XX:XX soit 6 champs de 2 caractères. Mais il y a le séparateur ":" que nous devons aussi prendre en compte. Le plus simple est de ce dire que nous cherchons en fait 5 blocs de 2 caractères suivit du ":" avec à la fin un bloc de 2 caractères.

Concernant les caractères constituant nos blocs, vu qu'il s'agit en fait d'une notation hexadécimale, il faut aussi en tenir compte. Pas la peine par exemple de rechercher toute lettre de l'alphabet, l'hexadécimal s'arrête à F. Nous pouvons aussi avoir des chiffres de 0 à 9. Pour signifier en expression régulière que nous recherchons des chiffres de 0 à 9 il faut utiliser la syntaxe suivante:

[0-9]

Pour les lettres de A à F celle-ci:

[A-F]

Il suffit de mélanger les 2 pour avoir la plage hexadécimale de 0 à F, et nous allons rajouter les minuscules, ce qui donne:

[0-9a-fA-F]

Cette expression donne un résultat dès qu'elle tombe sur un chiffre de 0 à 9, ou 1 lettre de a à f, ou 1 lettre de A à F. C'est déjà un bon début.

Pour indiquer dans une expression régulière le nombre d'occurrence que nous recherchons, il suffit de préciser ce nombre entre accolade. Nos blocs sont toujours constitués de 2 caractères, donc:

[0-9a-fA-F]{2}

Il nous manque plus que le séparateur ":" qui est un caractère spéciaux en expression régulière, il faut donc l'échapper avec \. Notre premier bloc sera donc:

[0-9a-fA-F]{2}\:

Ce premier bloc dans une adresse mac est présent 5 fois, nous allons donc dire que tout ce bloc doit être vu 5 fois de suite. Pour délimiter un bloc, il faut utiliser les parenthèses:

([0-9a-fA-F]{2}\:){5}

Nous terminons avec le dernier bloc, qui est en fait similaire au premier mais sans le séparateur:

([0-9a-fA-F]{2}

L'expression régulière complète est donc:

([0-9a-fA-F]{2}\:){5}[0-9a-fA-F]{2}

Nous pouvons la tester avec grep et l'option -E ou directement avec la commande egrep. Par exemple sur les fichiers de configuration réseau d'une Fedora:

cd /etc/sysconfig/network-scripts/
egrep -ho "([0-9a-fA-F]{2}\:){5}[0-9a-fA-F]{2}" ifcfg-eth*

options: -h pour ne pas indiquer le nom du fichier et -o pour n'afficher que ce qui correspond au résultat et non toute la ligne complète

Bash plus intelligent?

Edouard Bourguignon

Il est possible de rendre bash plus intelligent, en permettant le complètement des commandes (completion en anglais) jusque dans leurs arguments, du moins pour certaines. Pour cela il faut installer le logiciel bash-completion. Le paquet pour Fedora est bien adapté aux commandes Fedora ce qui le rend très utile. Il n'y a rien de magique, ce n'est pas non plus de l'introspection dynamique, bash-completion repose sur une sorte de base de données qui référence les commandes et leurs arguments.

Enfin bref, pour l'installer, sous Fedora, il suffit de taper la commande suivante:

yum install bash-completion

Pour l'activer sans avoir à se deloguer:

source /etc/bash-completion

Voici des exemples surpuissants que vous pouvez vous aussi utiliser chez vous:

ser[tab] ht[tab] res[tab] => service httpd restart
yu[tab] ins[tab] ligh[tab] => yum install lighttpd

Et oui encore un truc de faignasse d'admin :)

Une dernière petite astuce pratique, toujours sur la completion. Qui n'a jamais tapé trop vite au clavier un chemin, par ex "/Etc" au lieu de "/etc" à cause de la touche shift pour faire le "/"? Et bien il est possible de rendre insensible à la casse le complètement des commandes et chemins sous Bash. Pour cela il faut éditer le fichier "/etc/inputrc" pour imposer ce réglage de manière globale ou sinon "~/.inputrc" pour votre utilisateur seulement et ajouter une ligne (à la fin par exemple):

set completion-ignore-case on

Il faut se déloguer par contre, a moins que quelqu'un connaisse l'astuce pour faire relire ce fichier par bash. Pour vérifier que ça marche:

cd /E[tab] => cd /etc

Et voilà :)

Script de sauvegarde type snapshot

Fabien Amann Time Machine maison

script : vérifier que rTorrent est lancé

Fabien Amann Bash check_rtorrent.sh