Mot-clé - terminal

Fil des billets - Fil des commentaires

lundi, février 18 2013

Coloriser la sortie d'un programme

Développant sur Google Appengine en ce moment, en python, j'utilise les logs à foison. Ces logs sont pratique et ont un niveau d'information (WARNING, INFO, ERROR...). Mais la lisibilité n'est pas forcément adaptée, car en effet les logs sont simplement des lignes de texte. C'est alors qu'une idée m'a frappée (sans gravité, j'ai pas eut mal): et si je colorisai la sortie. Ma méthode fonctionne pour à peu près tous les programmes que vous utilisez dans un terminal, et peut être adaptée à pas mal de situations

Lire la suite...

jeudi, août 2 2012

Vim en moteur de slide - Vroom

Si vous suivez un peu mon blog, vous connaissez mon adoration pour le terminal de commande, vim et tout outil fonctionnant en mode console. J'ai toujours trouvé plus clair ce fonctionnement que de passer par des outils graphiques pour la moindre action. Aujourd'hui, c'est un outil de présentation (un slide si vous préférez) que j'ai découvert. Ça va vite, c'est pratique, c'est fonctionnel et ça marche avec Vim... En clair, ça a tout pour me plaire. Laissez-moi vous présenter "vroom"

Lire la suite...

dimanche, juin 3 2012

Correction orthographique et grammaticale avec Vim

J'en avais assez de voir que je tapais faute sur faute en préparant mes billets sous Vim... je suis mauvais en orthographe, et pire en grammaire. J'ai honte souvent de cette tare, alors j'ai décidé de fouiller pour trouver une méthode propre pour supprimer un bon paquets de fautes en utilisant mon éditeur favori. Voici ce que j'ai à vous proposer.

Lire la suite...

dimanche, mai 20 2012

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

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)

Lire la suite...

vendredi, avril 27 2012

Point de montage Google Drive

Google vient de sortir Google Drive, comprenez un espace de stockage dans le "cloud" (à distance, sur les serveur Google, avec mix des documents de google-docs). L'application de disque dur distant est accessible de plusieurs manières: Android, PC ou directement sur le net. Or sous Windows et Mac on a la possibilité d'utiliser un programme qui monte un disque sur l'ordinateur. Qui dit "monter" rappelle le point de montage Linux (unix...). Google a annoncé une version de Google Drive Linux pour bientôt mais en attendant vous pouvez encore utiliser le projet http://code.google.com/p/google-docs-fs/

Ce projet était à la base un système de montage simple utilisant fuse pour afficher les google-docs sur un disque monté localement. Mais comme Drive utilise le même point d'accès, ce (vieux) projet fonctionne très bien. Sous Fedora, il suffit de faire:

update merci à "hk", j'avais oublié le paquet python-gdata


su -c "yum install fuse-python python-gdata -y"

cd /tmp
hg clone https://code.google.com/p/google-docs-fs/
cd google-docs-fs
su -c "python setup.py install"

Reste alors à monter le dossier:

mkdir ~/GoogleDrive
gmount ~/GoogleDrive votre_user@gmail.com

On vous demande alors le mot de passe google, et hop le point de montage est créé:

mount
gmount.py on /home/patachou/GoogleDrive type fuse.gmount.py (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

Vous pouvez dés lors visiter le dossier, créer des répertoires, copier des données, ouvrir vos documents... et y accéder depuis votre mobile, le net... Reste à voir ce que l'application Google offrira de mieux que ce petit projet python, parce que pour le moment cela me convient tellement bien...

PS: vous pouvez ajouter ce point de montage dans /etc/fstab pour l'avoir actif tout le temps, mais comme je ne sais pas comment placer le mot de passe. Je vous tiens au courant si je trouve :)

dimanche, août 21 2011

Xmonad, le bureau productif orienté terminal

Vous utilisez certainement Gnome, KDE, ou XFCE (entre autre) pour afficher vos programmes. Le gestionnaire de fenêtre vous permet de déplacer le programme sur votre écran via la souris, vous avez des menus, des racourcis qui vous permettent de gérer tout ça. Je ne critique pas ce principe, il est pratique, assez standard et bien adapté à la plupart des utilisateurs. Mais nous ne sommes pas tous identiques. Certains, comme moi, utilisent surtout des terminaux, et n'aiment pas devoir passer la main du clavier à la souris pour gérer son espace de travail. Pire encore, nous n'avons en général pas besoin de la barre de titre, et devoir placer les fenêtres sur le bureau est une chose qui peut vraiment être un frein à la productivité.

Lire la suite...

mercredi, août 3 2011

Un chroot si rapide à créer

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 :)

vendredi, juillet 22 2011

Jouer avec le bash pour faire un benchmark

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... ;)

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