Sam & Max » shell http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Black awk down 8 http://sametmax.com/black-awk-down/ http://sametmax.com/black-awk-down/#comments Tue, 06 Jan 2015 10:26:20 +0000 http://sametmax.com/?p=10493

Ceci est un post invité de foX posté sous licence creative common 3.0 unported.

Introduction (sans douleur)

Qui n’a jamais rêvé d’avoir un shell Unix un peu plus pythonic ? Les oneliners en sed et Awk bien chiadés, c’est l’apanage des grands barbus en sandales et ça déchire, mais ça reste cryptique et la manipulation de liste et de chaînes de caractères est tout de même limitée. On peut dégainer perl en one line, comme ça c’est encore plus puissant mais moins lisible…

Et python dans tout ça ? En oneliner, ça craint, car le principe d’indentation ne facilite pas les choses et on finit avec une imbrication de bazar de parenthèses illisible.

La solution ? Pour se faire plaisir : une bonne pyp. Le bidule s’installe avec… pip (c’est une méta pipe).

pip install pyp

pyp (Python Power at the Prompt) va enchanter votre shell unix et vous envoyer au 7ème ciel. Petit tour d’horizon de la merveille.

Pyp et les strings

C’est la base quand on bricole des oneliners en shell, tripoter des strings.

ls *JPG | pyp "'mv', p, p.replace('JPG', 'jpg')"

Revoyons l’action au ralenti :

  • ls *JPG va nous lister tous les fichiers qui finissent par JPG dans le dossier courant.
  • Ensuite on envoie cela dans pyp avec un pipe Unix. Celui-ci va composer une ligne de commande qui est la concaténation d’une commande unix (mv pour renommer un fichier), ce qu’on aura reçu en entrée (qui s’appelle par convention “p”) et une version modifiée de p où l’on remplace JPG par jpg.

On voit ici que l’on utilise la méthode replace de la classe str python. On peut utiliser n’importe quelle méthode de str : lower, upper, title, strip(tease), count etc. Avec des petits bonus comme refindall(re) :-)

Ça donne quoi ma brave dame ? Et bien si on avait des fichiers appelés porn1.JPG et ass.JPG notre jolie commande renverrait :

mv porn1.JPG porn1.jpg
mv ass.JPG ass.jpg

Ok, bien gentil me direz-vous, mais qu’en fait-on ? Et bien ou l’on pipe ça dans le shell ( | sh) ou alors on passe l’argument -x (ou –execute) à pyp ou directement exécuter le résultat.

ls *JPG | pyp "'mv', p, p.replace('JPG', 'jpg')" | sh
# ou bien
ls *JPG | pyp -x "'mv', p, p.replace('JPG', 'jpg')"

Pourquoi on aime bien python ? Car il slice le bread comme un chef. Pyp aussi, oeuf corse, quelques exemples :

echo "sam-et-max" | pyp "p.split('-')[2]"
# max
 
# La même chose en plus court. Le m, comme minus, sous-entend qu'on split sur "-"
echo "sam-et-max" | pyp "m[2]"
# max
 
echo "sam-et-max" | pyp "m[0], m[2]"
# sam max

Comme vous avez vu, il y a un petit raccourci sympa avec m (comme minus) au lieu de p. C’est pas fini, vous en avez d’autres : d (dot) pour un point, w (whitespace) pour une espace, u pour underscore, s pour slash… Ils ont pensé à tout.

Des pyp à la chaîne

On tout de suite envie de remettre le couvert avec une autre pyp. C’est possible et même encouragé. Le symbole utilisé est le pipe unix | dans une commande pyp. Ce n’est donc pas un pipe du shell mais un pipe interne de pyp. Vous suivez ? Un petit exemple :

echo "sam et max" | pyp "w[0] | 'avant : ', o, 'après :', p"
# avant :  sam et max après : sam

Le p représente toujours le paramètre courant. Donc dans la seconde partie du pipe, c’est le premier élément de la liste issu du split de la chaîne “sam et max” sur l’espace (w comme whitespace). Vous suivez toujours ? Oui, bon. Et donc le o ? Et bien c’est le paramètre d’origine non modifié. Et il y a h (comme history ou comme hâlibi !) pour avoir le paramètre p à toutes les étapes de la chaîne de pipe… Beaucoup de puissance on vous dit !

On peut aussi rouler^w faire des join facilement avec les mêmes raccourcis. Par exemple on split sur les espaces puis join sur slash :

echo "sam et max aiment le lourd en fin de soirée" | pyp "w[:6]|s"
# sam/et/max/aiment/le/lourd

Une liste de pyp avec une belle pp

S’il y a un bien un truc qui envoie du bois avec python, c’est la gestion des listes. Pyp n’est pas en reste. C’est pp qui contient les listes. En avant :

ls | pyp "pp[3]"
# Affiche le troisième fichier

On peut utiliser toutes les méthodes standards de la classe list (sort, count etc.) plus quelques bonus :

# Équivalent de | sort | uniq

ls | pyp "pp.uniq()"
 
# Additionne tous les PID des process de machine.
# Ça ne sert à rien, mais c'est un exemple hein ?
ps -ef | pyp "w[1] | int(p) | sum(pp)"
 
# Voilà qui est plus utile. 
# Au passage, on note que la ligne d'en-tête est ignoré et ne fait pas planter pyp.
# Malin le lapin.
df -m | pyp "w[1] | int(p) | sum(pp)"

pyp au naturel

Pour compléter les fonctions python, pyp propose quelques fonctions maisons tout à fait sympathiques. Florilège :

echo "Sam Bill Max" | pyp "p.kill('Bill')"  # quand c'est pas bill, c'est kenny...
# Sam  Max
 
echo 124 | pyp "(int(p)/2+30)"
# 91
 
ls  | pyp "n, p"
# Liste des fichiers avec un numéro croissant devant
 
echo /home/fox/video/gangbang.avi  | pyp "'Dir='+p.dir, '\nFile='+p.file, '\nExt='+p.ext" # basename, dirname et ses amis
# Dir=/home/fox/video 
# File=gangbang.avi 
# Ext=avi
 
# On définit le séparateur de liste comme l'espace, 
# puis on regroupe la liste par deux élément
# et enfin on fait un join sur le caractère tiret (minus)
echo "1 2 3 4 5 6" | pyp "pp.delimit(' ') | pp.divide(2) | m"
# 1-2
# 3-4
# 5-6
 
ps -ef | pyp "w[1] | int(p) | max(pp)" 
# (le PID le plus grand)

pyp en intention ou intention de pyp ?

Il ne faut pas se gêner, on peut utiliser les excellentes listes en intention de Python. Voici tous les PID impaires :

ps -ef | pyp "w[1] | int(p) | [i for i in pp if i%2] | p "

L’industrie de la pyp c’est un truc de macro

Les bonnes choses, ça se garde, alors voilà :

ps -ef | pyp "w[1] | int(p) | [i for i in pp if i%2] | p " -s odd  # on enregistre la macro 'odd'
 
ps ef | pyp odd # c'est aussi simple que cela ;-)

pyp sur grand écran

Cette petite pépite est développée par Sony Pictures Imageworks pour ses besoins internes. Le développement n’est pas très collaboratif (un commit par release…) mais reste ouvert aux contributions externes. C’est sous une licence de type BSD.
Les loulous ont fait une jolie vidéo de tutorial très bling bling. C’est l’avantage de bosser dans le milieu :

Et bien plus encore…

Cet outil merveilleux possède encore des fonctionnalités qui vont vous le faire adorer comme son mode interactif avec une coloration syntaxique sympathique, la gestion de l’historique dans le pipe et beaucoup d’autres. Adieu sed, awk, uniq, sort et con sort, vous étiez mes premiers amours, mais pyp vous chasse dehors.

Ce n’est pas la seule ni la première tentative de faire la peau d’awk avec python. Sam avait déjà écrit un article sur une autre solution aussi appelée pyped.

C’est donc parfait ?

Oui, bien entendu. Aucun défaut, aucun bug. Ok… voici les limites :

      Perf de daube. Sur des petits volumes (quelques milliers de lignes) ça le fait. Au delà, ça rame. Quelques patch sont proposés pour diviser par trois le temps de traitement :-)
      Conso mémoire obcène. Idem, pour des petits volumes on s’en fout, mais sinon ça peut rapidement chiffrer. Pourquoi ? Le machin ne fonctionne pas en stream, tout est gardé en mémoire et à chaque étape de transformation (pour permettre d’accéder à l’historique).
      C’est installé sur votre pc, mais pas partout, contrairement à ce bon vieux awk.

Amusez vous bien, celui qui fait la plus jolie commande pyp dans les commentaires aura le droit à un bisous.

]]>
http://sametmax.com/black-awk-down/feed/ 8
Rejouer un session de terminal avec playitagainsam 10 http://sametmax.com/rejouer-un-session-de-terminal-avec-playitagainsam/ http://sametmax.com/rejouer-un-session-de-terminal-avec-playitagainsam/#comments Thu, 22 May 2014 08:29:36 +0000 http://sametmax.com/?p=10298 playitagainsam, ou PIAS a pour but de rejouer des sessions shell: il lance un shell, enregistre ce qu'on y a tapé, et quand on quitte le shell, sauvegarde le tout dans un fichier. Ensuite, on peut lire le contenu du fichier et revoir la session shell telle qu'elle a été tapée.]]> Combien de fois, durant une formation, on m’a demandé si je pouvais donner un dump de la session shell.

playitagainsam, ou PIAS, a exactement pour but de faire cela: il lance un shell, enregistre ce qu’on y a tapé, et quand on quitte le shell, sauvegarde le tout dans un fichier. Ensuite, on peut lire le contenu du fichier et revoir la session shell telle qu’elle a été tapée.

C’est un programme Python, on peut donc le pip installer :

pip install playitagainsam --user

Ensuite, on lance une session à enregistrer avec la sous commande record :

pias record nom_du_fichier_ou_sauver_l_enregistrement

PIAS va lancer un nouveau shell, par défaut le même que votre shell actuel (souvent bash, pour moi fish), mais vous pouvez préciser un type de shell spécial avec --shell. Ex :

pias record ex1 --shell ipython

A partir de là il n’y a rien à faire. On peut travailler normalement et oublier qu’on a utilisé PIAS. Une fois qu’on a terminé sa petite affaire, il suffit de sortir du shell (CTRL + D, exit, etc), et la session va être sauvegardée dans un format JSON facile à corriger à la main si vous souhaitez la rendre plus agréable :

{
  "events": [
    {
      "act": "OPEN",
      "size": [
        162,
        33
      ],
      "term": "1c53f048e3a74984b2a93af175e24e87"
    },
    {
      "act": "PAUSE",
      "duration": 0.10042214393615723
    },
    {
      "act": "WRITE",
      "data": "\u001b]0;sam@sametmax.com: /tmp\u0007sam@sametmax.com:/tmp$ ",
      "term": "1c53f048e3a74984b2a93af175e24e87"
    },
    {
      "act": "ECHO",
      "data": "touch essai",
      "term": "1c53f048e3a74984b2a93af175e24e87"
...
}

Quand vous voulez rejouer la session :

pias play fichier_d_enregistrement

Par défaut il faut appuyer sur une touche quelconque du clavier pour voir apparaitre chaque caractère, donnant l’impression que vous êtes un hacker de Hollywood. C’est rigolo, mais parfaitement chiant à la longue. On peut faire jouer la session automatiquement avec l’option --auto-type qui va taper chaque ligne automatiquement. Il suffira alors d’appuyer sur entrée à chaque ligne pour avoir le résultat suivant. C’est mon mode préféré.

Si vous êtes un gros feignant, vous pouvez tout jouer en automatique en rajoutant l’option --auto-waypoint qui va vous dispenser de taper entrée à chaque fin de ligne. Ex :

pias play ex1 --auto-type --auto-waypoint

La session jouée est simulée. Elle n’a aucun impacte sur le système. Si vous faites un mkdir dans bash ou un shutil.rmtree dans python, ça ne fera rien.

Néanmoins, parfois il est utile d’avoir le effets réels des commandes. Dans ce cas on peut utiliser --live-replay. Attention, faites bien gaffe à ce que vous allez jouer…

playitagainsam est intéressant pour tout ce qui est formation et tutorial, d’autant plus qu’il existe un player javascript pour faire la démonstration de vos sessions shell sur un blog ou un slideshow.

]]>
http://sametmax.com/rejouer-un-session-de-terminal-avec-playitagainsam/feed/ 10
Profiter du notebook de IPython 23 http://sametmax.com/profiter-du-notebook-de-ipython/ http://sametmax.com/profiter-du-notebook-de-ipython/#comments Wed, 23 Oct 2013 13:53:15 +0000 http://sametmax.com/?p=7507 IPython est un des outils qui me font trouver la programmation Python plus agréable que dans tous les autres langages : un shell avec tellement d’astuces intégrées que ça donne envie de vomir des arc-en-ciel.

Aujourd’hui je vais vous parler d’une fonctionnalité fantastique est très peu connue de IPython : le notebook.

Si vous êtes scientifique ou manipulez pas mal de graphiques et de données numériques, c’est un must have. Mais personnellement je trouve que c’est aussi un fantastique outil d’éducation, c’est génial pour les cours, les démos, et expérimenter avec du code inconnu.

Ça se présente sous la forme d’un shell IPython intégré dans une page Web, mais que l’on peut avoir sur son desktop, pas besoin d’avoir un serveur distant. Si vous avez un peu de temps, voici une vidéo de démo (avec un musique horrible) :

L’installation sous Ubuntu, c’est juste :

sudo apt-get install ipython-notebook

Pour Windows, il me semble, de mémoire, que c’est intégré dans l’exe. Pour Mac, je ne sais pas.

Et derrière il suffit de lancer la commande :

ipython notebook

Et il va vous ouvrir votre navigateur avec un onglet sur votre notebook.

L’intérêt principal du notebook est que TOUT le code est coloré et est modifiable comme sur dans fichier mais TOUT le code est exécutable (et affiche son résultat juste après chaque ligne) comme dans un shell iPython, avec completion du code. Le meilleur des deux mondes quoi.

En prime on peut embeder du markdown (et donc des liens, des images, etc) dans le même notebook, sauvegarder ça pour plus tard, le partager, etc.

Personnellement, j’ai ceci dans mon .bashrc :

notebook () {
    processes=$(ps aux | grep -i -P "ipython notebook" | wc -l)
    if [[ $processes -lt 2 ]]
    then
        pushd /tmp
        nohup ipython notebook --port 8889 $1 &
        popd
    else
        firefox http://127.0.0.1:8889
    fi
}

Comme ça en une commande je lance le serveur du notebook sur le port que je veux si il ne tourne pas, et si il tourne, j’ouvre firefox et ouvre un onglet dessus.

Quelques autres options très utiles :

–pylab : Charger plein de libs pour transformer IPython en un matlab killer.
–gui=lib : permet d’intégrer l’event loop de QT, wx, gtk, etc.
–ip=0.0.0.0 : si on veut que d’autres puisse accéder à notre notebook.

Il existe un espèce de pastebin spécialement fait pour le notebook, qui permet de partager ses expérimentations.

]]>
http://sametmax.com/profiter-du-notebook-de-ipython/feed/ 23
Nouvelle config iPython 9 http://sametmax.com/nouvelle-config-ipython/ http://sametmax.com/nouvelle-config-ipython/#comments Sun, 19 May 2013 17:24:44 +0000 http://sametmax.com/?p=6158 customiser ce shell. Voici ce que j'ai dans mon ./.config/ipython/profile_default/ipython_config.py...]]> J’ai bricolé une config pour iPython dernièrement. Rappelez-vous, on peut complètement customiser ce shell.

Voici ce que j’ai dans mon ./.config/ipython/profile_default/ipython_config.py:

c.TerminalIPythonApp.exec_lines = [
'doctest_mode on',
'from __future__ import unicode_literals, absolute_import, division',
'import sys',
'import os',
'import re',
'import json',
'import base64',
'import calendar',
'import csv',
'import datetime',
'import itertools',
'import random',
'import hashlib',
'import tempfile',
'import argparse',
'import math',
'import random',
'import subprocess',
'from glob import glob',
'from uuid import uuid4',
'from datetime import datetime, timedelta',
'from collections import Counter, OrderedDict',
"""
def initial_imports():
 
    # ne faites pas ça dans un code de prod :-)
    global path, relativedelta, requests 
 
    print("\\nImported : 'sys', 'os', 're', 'json', 'base64', 'calendar', 'csv', 'datetime', 'itertools', 'random', 'hashlib', 'tempfile', 'argparse', 'math', 'random', 'glob', 'uuid4', 'datetime', 'timedelta', 'Counter', 'OrderedDict', 'subprocess'\\n")
 
    try:
        from path import path
        print('Imported : "path"')
    except ImportError:
        print("'path' is not available")
 
    try:
        from dateutil import relativedelta
        print('Imported : "relativedelta"')
    except ImportError:
        print("'dateutil' is not available")
 
    try:
        import requests
        print('Imported : "requests"')
    except ImportError:
        print("'requests' is not available")
 
    try:
        env = os.environ['VIRTUAL_ENV']
        print("\\nENV '{}'. You can import:\\n".format(os.path.basename(env)))
        cmd = subprocess.check_output([env + "/bin/pip", "freeze"],
                                      stderr=subprocess.STDOUT).strip().split("\\n")
        p = re.compile(r'(^.*\:\s)|((#|@).*$)|(==.*$)')
        print("'" + "', '".join(sorted(set(os.path.basename(p.sub('', f)) for f in cmd))) + "'")
    except KeyError:
        pass
 
    print('')
""",
"initial_imports()"
]

Du coup, au démarrage d’iPython j’ai les bénéfices suivant :

  • Comportement de Python 3 pour l’unicode, les imports et la division. Ils sont plus sains et facile à manipuler (plus besoin de préfixer de ‘u’ les chaînes par exemple).
  • J’ai tout de suite sous la main une tonne de modules que j’utilise souvent sans avoir à les importer (os, datetime, random, etc).
  • J’importe aussi des modules optionnels (path, requests…).
  • Je sais si je suis dans un environnement virtuel, et si oui, ce qu’il y a installé dedans.

Je vire aussi la bannière de démarrage :

c.TerminalIPythonApp.display_banner = False

Et hop, mon affichage au démarrage ressemble à ça :

$ ipython
Exception reporting mode: Plain
Doctest mode is: ON

Imported : 'sys', 'os', 're', 'json', 'base64', 'calendar', 'csv', 'datetime', 'itertools', 'random', 'hashlib', 'tempfile', 'argparse', 'math', 'random', 'glob', 'uuid4', 'datetime', 'timedelta', 'Counter', 'OrderedDict', 'subprocess'

'path' is not available
'dateutil' is not available
Imported : "requests"

ENV 'my_env'. You can import:

'BeautifulSoup', 'Django', 'Fabric', 'Jinja2', 'Pillow', 'Pygments', 'Sphinx', 'URLObject', 'Werkzeug', 'argparse', 'beautifulsoup4', 'colorlog', 'distribute', 'django-appconf', 'django-bootstrap-pagination', 'django-bootstrap-toolkit', 'django-compressor', 'django-debug-toolbar', 'django-extensions', 'django-guardian', 'django-loginas', 'django-model-utils', 'django-pdb', 'django-pytest', 'django-rest-framework.git', 'django-template-repl', 'docutils', 'easy-thumbnails', 'feedparser', 'gunicor

Ça fait un gros bloc visuellement, mais ça ne s’affiche qu’une fois, et le délai est acceptable.

Si j’ai besoin de l’info à nouveau, je peux toujours appeler :

initial_imports()

Que ce genre de choses soient possibles et faciles me font adorer Python. La force du langage, ce n’est pas seulement son core, c’est tout son environnement, ses libs, ses outils qui gravitent autour qui rendent l’expérience de dev fantastique.

]]>
http://sametmax.com/nouvelle-config-ipython/feed/ 9
A l’intérieur de mon .bashrc 22 http://sametmax.com/a-linterieur-de-mon-bashrc/ http://sametmax.com/a-linterieur-de-mon-bashrc/#comments Tue, 22 Jan 2013 10:26:44 +0000 http://sametmax.com/?p=4238 .bashrc donne rapidement lieu dans les comments à un concours de celui qui a la plus longue (jusqu'à ce qu'arrive un utilisateur de zsh, et alors commence le concours de celui qui pisse le plus loin). Mais bon, aujourd'hui j'ai la flemme d'écrire un article complet.]]> Généralement montrer son .bashrc donne rapidement lieu dans les comments à un concours de celui qui a la plus longue (jusqu’à ce qu’arrive un utilisateur de zsh, et alors commence le concours de celui qui pisse le plus loin). Mais bon, aujourd’hui j’ai la flemme d’écrire un article complet.

Rappel : le .bashrc c’est le fichier qui est automatiquement chargé au démarrage du shell bash, le shell par défaut sur la plupart des Unix incluant Mac et Ubuntu.

Donc si vous voulez avoir une expérience de travail personnalisée dans votre terminal, c’est dans ce fichier que ça se passe.

Personnellement, j’ai tout le bordel que met Ubuntu par défaut (notamment les trucs avec les autocomplétions de partout). En en prime je rajoute :

# un raccourcis pour lancer Redis car je le met sur off par défaut mais je le 
# lance souvent
 
function redis {
    if [ ! -e "/var/run/redis/redis-server.pid" ] ; then
        sudo service redis-server start
    fi
}
 
# un tas de raccourcis type
 
function projet_django {
    workon projet_django;
    cd /home/sam/Work/projet_django/repo/projet_django;
 
    if [[ $# -ne 0 ]]; then
        ./manage.py $@
    fi
}
alias sb='projet_django'
 
# CF: http://sametmax.com/un-alias-bash-pour-django-virtualenv-dont-je-ne-peux-plus-me-passer/
 
 
# fonction fétiche de bourrin
 
function killbill {
    BAK=$IFS
    IFS=$'\n'
    for id in $(ps aux | grep -P -i $1 | grep -v "grep" | awk '{printf $2" "; for (i=11; i<NF; i++) printf $i" "; print $NF}'); do 
        service=$(echo $id | cut -d " " -f 1)
        if [[ $2 == "-t" ]]; then
            echo $service \"$(echo $id | cut -d " " -f 2-)\" "would be killed"
        else
 
            echo $service \"$(echo $id | cut -d " " -f 2-)\" "killed"
            kill -9 $service
        fi
    done
    IFS=$BAK
}
 
# que j'ai un peu amélioré depuis http://sametmax.com/tu-vas-crever-oui/
 
 
# une fonction pour commiter rapidement 
function commit {
    git commit -m "`echo "$*" | sed -e 's/^./\U&\E/g'`"
}
alias co=commit;
 
# en gros on tappe "co message de commit". Sans guillement, sans rien.
 
# des completions pour manage.py et git
 
source /home/sam/.django_bash_completion
source /home/sam/.git-completion.bash
 
# activation du cache de pip pour éviter de télécharger 20 fois la même lib
 
PIP_DOWNLOAD_CACHE='/opt/pip-cache';
export PIP_DOWNLOAD_CACHE;
 
# un super outil pour un git plus user friendly
 
[ -s "/home/sam/.scm_breeze/scm_breeze.sh" ] && source "/home/sam/.scm_breeze/scm_breeze.sh"
alias c="git_index"
 
# j'en avais parlé ici : http://sametmax.com/scm-breeze-facilite-la-selection-de-vos-fichiers-a-commiter-sous-git-avec/
 
 
# un prompt personalisé tout en couleur
# formaté comme ça: [nom du virtualenv] sam ~/path (branche git) $
 
source ~/.prompt.bash
 
# le fichier ressemble à ça : http://0bin.net/paste/d103a91dc41818462da0c8468ddddf4141f2efd6#dKr6qWHfAVZsSnOQ7fA4pPQ3Dquhz0Oj1b2OF8xw6vA=
 
# la configuration de virtualenv wrapper 
export WORKON_HOME=/home/sam/.virtualenvs
mkdir -p $WORKON_HOME
source /usr/local/bin/virtualenvwrapper.sh
 
# plus de détails ici : http://sametmax.com/les-environnement-virtuels-python-virtualenv-et-virtualenvwrapper/
 
 
# j'ai récément succombé aux sirène du virtualenv automatique
# j'avais beaucoup d'a priori (particulirement écraser la commande CD)
# mais à l'usage, c'est pratique
has_virtualenv() {
    if [ -e .venv ]; then
        workon `cat .venv`
    fi
}
venv_cd () {
    builtin cd "$@" && has_virtualenv
}
alias cd="venv_cd"
has_virtualenv
 
# en gros ça m'active un virtualenv si il y a un fichier .venv avec un nom
# de virtualenv dedans dans le dossier courrant
 
 
# je vous en parlais récement (http://sametmax.com/configurer-votre-terminal-pour-quil-vous-notifie-de-la-fin-dune-commande-longue/)
# c'est pour avoir une notifi à la fin des commandes longues 
notify_when_long_running_commands_finish_install
 
 
# ca c'est un truc de feignasse car je me souviens jamais comment extraire 
# en ligne de commande tel ou tel format
 
extract () {
    if [ -f $1 ]
    then
        case $1 in
            (*.7z) 7z x $1 ;;
            (*.lzma) unlzma $1 ;;
            (*.rar) unrar x $1 ;;
            (*.tar) tar xvf $1 ;;
            (*.tar.bz2) tar xvjf $1 ;;
            (*.bz2) bunzip2 $1 ;;
            (*.tar.gz) tar xvzf $1 ;;
            (*.gz) gunzip $1 ;;
            (*.tar.xz) tar Jxvf $1 ;;
            (*.xz) xz -d $1 ;;
            (*.tbz2) tar xvjf $1 ;;
            (*.tgz) tar xvzf $1 ;;
            (*.zip) unzip $1 ;;
            (*.Z) uncompress ;;
            (*) echo "don't know how to extract '$1'..." ;;
        esac
    else
        echo "Error: '$1' is not a valid file!"
        exit 0
    fi
}
 
# ça date de http://sametmax.com/decompresser-sous-linux-en-ligne-de-commande/
 
# et quelques alias pour des tâches de tous les jours
 
alias ..='cd ..'
alias ...='cd ../../'
alias ....='cd ../../../'
alias .....='cd ../../../../'
alias ......='cd ../../../../../'
 
alias process='ps aux | grep'
alias serve="python -c 'import SimpleHTTPServer; SimpleHTTPServer.test()'"
]]>
http://sametmax.com/a-linterieur-de-mon-bashrc/feed/ 22
Quelques bonnes raisons de plus d’utiliser iPython 7 http://sametmax.com/quelques-bonnes-raisons-de-plus-dutiliser-ipython/ http://sametmax.com/quelques-bonnes-raisons-de-plus-dutiliser-ipython/#comments Sun, 23 Dec 2012 18:01:36 +0000 http://sametmax.com/?p=3644 iPython, ola, iPython, il déchire sa génitrice avec une poutrelle en verre pilé.]]> Le shell Python est vraiment pratique pour expérimenter, apprendre le langage, tester un snippet vitos ou administrer son site à distance. Mais iPython, ola, iPython, il déchire sa génitrice avec une poutrelle en verre pilé.

Voici quelques commandes qui vous donneront moult raisons de plus pour très vite installer ce shell alternatif.

Autocall

Taper des parenthèses et des guillemets, c’est sooooooo 1995. iPython peut vous les rajouter automatiquement dans les appels de fonctions, il faut juste préfixer de “/”, “,” ou “;” votre appel de fonction pour qu’il fasse la conversion:

/f 1,2 => f(1,2)
,f 1 2 => f("1","2")
;f 1 2 => f("1 2")

Accès au shell système

Préfixez votre commande d’un “!” bien couillu, et iPython va vous exécuter ça dans le shell système (par exemple bash) et vous retourner le résulat:

>>> ! cat /etc/fstab | grep 'ext4'
UUID=e33c5b98-1570-44d6-a32f-5e7970e1e588 /               ext4    errors=remount-ro 0       1

Oui, oui, on est dans un shell Python là. Ou comment bien faire chier la coloration syntaxique de votre blog.

Et on peut mettre tout ça dans une variable et le traiter en Python derrière:

>>> files = !ls
>>> [f.upper() for f in files]
['BUREAU', 'DOCUMENTS', 'EXAMPLES.DESKTOP', 'IMAGES', 'MOD\xc3\xa8LES', 'MUSIQUE', 'PUBLIC', 'T\xc3\xa9L\xc3\xa9CHARGEMENTS', 'UBUNTU ONE', 'VID\xc3\xa9OS',]

A noter que tout est exécuté dans un autre process, ainsi !cd n’aura aucun effet. Mais tout est prévu: %cd et %pwd proxient tout ça vers os.chdir et os.getcwd :-)

Debugger

Entrez %timeit expression pour qu’il qu’iPython vous l’exécute 10000000 fois et vous donne sa performance.

>>> %timeit x=2**100
10000000 loops, best of 3: 22.5 ns per loop

Autre commande: %pdb vous lancera automatiquement votre débuggeur favoris si une exception se lève durant votre session.

Se faciliter la vie

%edit ouvre un editeur (par défault VI sous nunux, mais c’est configurable), et si vous sauvegardez, le contenu tapé est récupéré et exécuté par iPython. Génial pour les bouts de code trop relou à taper sur le prompt.

%gui qt|wx|gtk lance l’intégration de la main loop d’un des toolkits graphiques afin pour de pouvoir faire mumuse avec des widgets sans bloquer votre shell.

Vous étiez vous demandé pourquoi le prompt iPython était plein de In et de Out, et pas de >>> ? Parce que tout l’historique est numéroté, et accessible:

In [38]: 1 + 1
Out[38]: 2
 
In [39]: In[38]
Out[39]: u'1 + 1'
 
In [40]: Out[38]
Out[40]: 2

Mais vous pouvez aussi utiliser %doctest_mode qui donne à votre prompt un air de shell Python normal. L’avantage ? On peut copier le contenu d’un autre shell dedans (et donc d’une doctest) avec les chevrons !

In [49]: %doctest_mode
Exception reporting mode: Plain
Doctest mode is: ON
>>> >>> for pom in ('pom', 'pom', 'pom', 'pom'):
...     ...     print pom
...     ... 
pom
pom
pom
pom
]]>
http://sametmax.com/quelques-bonnes-raisons-de-plus-dutiliser-ipython/feed/ 7
Personnalisez le démarrage d’iPython 8 http://sametmax.com/personnalisez-le-demarrage-dipython/ http://sametmax.com/personnalisez-le-demarrage-dipython/#comments Sun, 16 Dec 2012 13:14:54 +0000 http://sametmax.com/?p=3643 iPython, c’est bon. Et ça peut être encore meilleur.

Avant on ajoutait un peu de sel à notre super shell en éditant les fichiers .ipython/ipythonrc et .ipython/ipy_user_conf.py. Mais ça c’était avant.

Maintenant on fait :

$ ipython profile create

Ce qui va créer un fichier ~/.config/ipython/profile_default/ipython_config.py (et ipython_qtconsole_config.py si vous avez installé la version qt).

Il ne vous reste plus qu’à éditer ce fichier pour personnaliser le démarrage de iPython.

Executer du code au démarrage

N’importe quelle ligne de code Python ou de commande magique (les trucs qui commencent pas ‘%’ qui ne fonctionnent que dans iPython) !

Très utile pour les imports par exemple. Voici ce que je fais moi au démarrage :

c.TerminalIPythonApp.exec_lines = [
'%doctest_mode',
'import os, sys, re, json',
'from datetime import datetime, timedelta',
'''
try:
    from path import path
except ImportError:
    pass
''',
'''
try:
    import requests
except ImportError:
    pass
''',
'''
try:
    from batbelt.structs import *
    from batbelt.objects import attr
    from batbelt.strings import slugify, normalize, json_dumps, json_loads
except ImportError:
    pass
'''
]

Du coup j’ai quasiment jamais besoin d’importer un truc, car ce que j’utilise le plus est déjà là. %doctest_mode me permet de coller des docstrings sans me fouler.

Programmation graphique

iPython possède une boucle principale. Les toolkits graphiques aussi. Si vous faites vos essais du code du second dans le premier, ça va bloquer. Heureusement on peut demander à iPython d’intégrer la main loop d’un des toolkits graphiques les plus célèbres en choisissant parmi : ‘qt’, ‘wx’, ‘gtk’, ‘glut’, ‘pyglet’ et ‘osx’ et en settant :

c.TerminalIPythonApp.gui = 'qt'

Virer le header

Quand on lance le shell, il vous raconte sa vie. Pour lui dire de fermer sa gueule :

c.TerminalIPythonApp.display_banner = False

Lancer un script complet

Bon, ça c’est si vous avez de gros besoins…

c.TerminalIPythonApp.file_to_run = '/path/to/script.py'

Sauter la confirmation à la fermeture

Oui, je suis sûr te vouloir te fermer connard ! Tu crois que j’ai appuyé sur Ctrl + d par erreur en éternuant ?

c.TerminalInteractiveShell.confirm_exit = False

Choisir son éditeur externe

Si vous tapez %edit dans iPython, il ouvre un éditeur. Vous tapez votre code, vous sauvegardez, vous fermez. Et iPython récupère le code et l’éxécute. Par défault il utilise VI. On peut faire mieux.

c.TerminalInteractiveShell.editor = '/chemin/vers/sublime-text -w'
]]>
http://sametmax.com/personnalisez-le-demarrage-dipython/feed/ 8
Le _ (underscore) dans le shell interactif Python 12 http://sametmax.com/le-_-underscode-dans-le-shell-interactif-python/ http://sametmax.com/le-_-underscode-dans-le-shell-interactif-python/#comments Thu, 20 Sep 2012 19:51:30 +0000 http://sametmax.com/?p=1186 C’est une fonctionnalité que peu de gens connaissent, pourtant très utile.

Dans le shell Python, à chaque fois qu’on évalue une expression, le résultat affiché est référencé dans la variable _.

>>> 1 + 1
2
>>> print _
2

On peut évidement la réutiliser comme n’importe quelle variable:

>>> range(5)
[0, 1, 2, 3, 4]
>>> [x * 2 for x in _]
[0, 2, 4, 6, 8]

Pour éviter d’effacer la variable trop souvent, quand le résultat retourné est None, _ ne change pas, donc il ne change pas quand on print :-)

>>> 1 > 2 or None
>>> _
[0, 2, 4, 6, 8]
>>> print 'a'
a
>>> _
[0, 2, 4, 6, 8]

Ça ne marche que dans le shell, pas dans un script.

]]>
http://sametmax.com/le-_-underscode-dans-le-shell-interactif-python/feed/ 12
Etre prévenu quand une longue commande a fini son éxécution sous Ubuntu et Mac 7 http://sametmax.com/etre-prevenu-quand-une-longue-commande-a-fini-son-execution-sous-ubuntu-et-mac/ http://sametmax.com/etre-prevenu-quand-une-longue-commande-a-fini-son-execution-sous-ubuntu-et-mac/#comments Mon, 18 Jun 2012 18:19:24 +0000 http://sametmax.com/?p=947 Quand on lance une commande qui tourne pendant un certain bout de temps (typiquement une migration ou un encodage en masse), on a pas envie d’avoir les yeux vissés sur le terminal pour savoir quand elle se termine.

Alertes sous Ubuntu

Entrez simplement:

alert "Encore merci et bonne chance, nous sommes avec vous."

Ceci va faire apparaitre une notification avec le message passé en paramètre.

Pour avoir l’alerte lancée une fois une commande terminée, il suffit de la mettre just après, derrière un point virgule:

sleep 5; alert

Le message sera alors la commande précédente.

Pour ceux qui ne sont pas sous Ubuntu, on peut créer la commande manuellement (Ubuntu ne fait que mettre cette ligne par défaut dans le .bashrc):

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

Il faut bien entendu s’assurer que la commande “notify-send” soit installée.

Alertes sous Mac

Mac vient avec un synthétiseur vocal qui peut être utilisé de manière similaire:

say "I just want to thank you both, we're all counting on you."

Le Mac va alors vous lire la phrase à haute, hum… voix. Il faut bien sûr s’assurer que l’on a le volume réglé en conséquence sinon l’alerte risque de ne pas se passer comme prévu :-)

Un bon truc donc pour foutre la honte à votre collègue de bureau, mettez le sond à fond et lancez juste avant la pause déjeûner dans un onglet discretos:

sleep 5000; say "Oh yeah bitch, just like that, just like that. Suck it ! Suck it hard. Oh Yeaaaaaaaaaaaaaa!"

C’est particulièrement perturbant sur une voix de synthèse.

Cette commande fonctionne mieux avec des phrases en anglais.

Attention cependant, ces deux astuces ne fonctionnent qu’en local, puisse qu’un ordinateur distant n’a pas accès au système de notification de votre desktop. Un défaut ennuyeux car on lance souvent des commandes longues via SSH.

]]>
http://sametmax.com/etre-prevenu-quand-une-longue-commande-a-fini-son-execution-sous-ubuntu-et-mac/feed/ 7