Sam & Max » bash 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 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
Remplacer sed, awk, cut et Perl par Python (= orgasme pour sysadmin) 26 http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/ http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/#comments Sat, 14 Dec 2013 08:28:41 +0000 http://sametmax.com/?p=8261 La force de Perl c’est qu’il permettait de piper des données directement via la ligne de commande pour faire des manipulations rapides.

C’est pour cela que c’était devenu les choix des sysadmins. Parce que jusqu’ici, le choix c’était soit de faire un truc simple en connaissant par coeur la tool box GNU, soit ouvrir un fichier et faire un script.

Python ne permet pas de piper des données directement dans la commande, mais des projets ont vu le jour pour le faire.

Il y a le projet pyp, que l’on doit à Sony Pictures Imageworks qui avait besoin de se simplifier l’automatisation des tâches de build pour ses films.

Et il y a pyped, dont j’avais brièvement parlé ici (article qui mérite d’être mis à jour vu que j’ai remplace dateutils par arrow).

Les deux étaient sympas, mais avait des syntaxes alambiquées, n’étaient pas compatibles python 3 et manquaient d’imports auto. Cependant, pyped est récemment passé en v1.0, donc stable, et a une toute nouvelle approche de syntaxe qui rend la bestiole super agréable à utiliser.

Présentation.

Stdin, ligne à ligne

L’installation est bateau, c’est du pip :

pip install --user pyped

Et derrière, on obtient la commande pyp. Elle s’utilise essentiellement à la suite d’une autre commande. Typiquement :

cat /etc/fsta | pyp "un truc"

L’astuce, c’est que “un truc” peut être n’importe quelle expression Python. Généralement une expression qui print() quelque chose.

Or, Pyped met automatiquement à disposition de cette expression deux variables :

  • La ligne en cours, dans la variable x.
  • Le numéro de la ligne en cours, dans la variable i.

L’expression Python est appelée une fois pour chaque ligne.

Par exemple, supposons que j’ai un fichier “fortune.txt” contenant :

bitcoin (btc) : 5
euros () : 100
dollars ($) : 80

Si je veut tout mettre en majuscule, je fais :

$ cat fortune.txt | pyp "print(x.upper())"
BITCOIN (BTC) : 5
EUROS () : 100
DOLLARS ($) : 80

On peut mettre plusieurs expressions d’affilé. Ainsi, si je veux récupérer la somme et le symbole uniquement :

$ cat fortune.txt | pyp "devise, sign, _, value = x.split()" "sign = sign.strip('()')" "print('%s%s' % (value, sign))"
5btc
10080$

Ok, c’est plus long que perl, mais vachement plus facile à écrire et à relire. Et j’utilise un langage que je connais déjà. Et pas besoin de faire un mix incompréhensible de sed, awk et autre cut.

Si j’ai vraiment besoin de lisibilité, je peux même le mettre sur plusieurs lignes :

$ cat fortune.txt | pyp "                                                                                                 
devise, sign, _, value = x.split() 
sign = sign.strip('()') 
print('%s%s' % (value, sign))  
"
5btc
10080$

Vous aurez noté que j’utilise print() et que je semble ne pas me soucier de l’unicode. C’est parceque pyped fait ça au début du script :

from __future__ import print_function, unicode_literals, division, absolute_imports

Du coup, on est bien en Python 2.7, mais on bénéficie de la division améliorée, de la fonction pour printer, des imports absolus et surtout, de l’unicode partout. D’ailleurs pyped vous transforme x pour que ce soit un objet unicode.

Dans tous les cas, pyped est compatible Python 3.

Tout traiter d’un coup

Parfois, on a besoin d’avoir accès à toutes les lignes, pas juste les lignes une à une. pyped permet cela avec l’option -i. Les variables x et i disparaissent au profit de la variable l, qui contient un itérable sur toutes les lignes.

Par exemple, envie de trier tout ça ?

cat fortune.txt | pyp -i "
lignes = (x.split() for x in l)
lignes = sorted((v, s.strip('()')) for d, s, _, v in lignes)
for ligne in lignes: print('%s%s' % ligne)
"
100€
5btc
80$

Moar options

Lisez la doc, car il y a d’autres options du genre éviter que pyped vous strip automatiquement le ligne break, forcer l’encoding, etc.

Parmi les trucs les plus utiles, il y a l’option -b qui permet de lancer un code avant la boucle. Pratique pour importer des trucs genre le module tarfile pour extraire une archive avant d’utiliser son contenu.

Néanmoins la plupart du temps on a rien besoin d’importer car pyped importe déjà automatiquement les modules les plus utiles : maths, datetime, re, json, hashlib, uuid, etc.

]]>
http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/feed/ 26
Variables d’environnement utilisées par Python 9 http://sametmax.com/variables-denvironnement-utilisees-par-python/ http://sametmax.com/variables-denvironnement-utilisees-par-python/#comments Wed, 31 Jul 2013 15:07:36 +0000 http://sametmax.com/?p=6987 Avant même l’utilisation d’options, de fichiers de conf, et outils installés, les variables d’environnement sont un moyen pratique de configurer un programme. Il s’agit simplement d’une variable globale accessible dans le shell courant.

Par exemple, sous bash, pour créer une variable, il suffit de faire :

$ NOMDEVARIABLE='valeur' # mettre la variable à la bonne valeur
$ export NOMDEVARIABLE # rendre la variable globale

La convention est de mettre leur nom en majuscule.

Et pour afficher la variable, il suffit de faire :

$ echo $NOMDEVARIABLE
valeur

Pourquoi c’est pratique ? Et bien parce qu’un programme comme Python va aussi aller regarder dans ces variables d’environnement pour se configurer. Donc, si vous settez la variable avec le bon nom dans votre shell et que vous lancez l’interpréteur Python, vous pouvez démarrer ce dernier avec un comportement différent, comme le ferait une option ou un fichier de config. La différence ? La variable est valable pour toute la session de shell, donc même si vous ressortez de l’interpréteur Python, et que vous le relancez, tant que vous êtes dans la même session de shell, la configuration reste la même.

Variables attendues

PYTHONSTARTUP: un module à exécuter au démarrage de Python.

Pratique si vous savez que vous allez utiliser souvent le même code dans votre prochaine session de travail avec le shell. Par exemple, je crée un module /tmp/imports.py et je met dedans :

import json
import pickle
from datetime import datetime

Ensuite, je set ma variable :

$ PYTHONSTARTUP='/tmp/imports.py' 
$ export PYTHONSTARTUP

Et en lançant l’interpréteur, même en sortant et en le relançant 50 fois de suite, je n’ai pas à importer ces modules.

PYTHONPATH : une liste de dossiers séparés par ‘:’ qui va être ajouté à sys.path

Vous savez qu’il y a des packages qui ne sont pas dans le PYTHON PATH, donc non importables. Mais pour le moment, vous voulez les utiliser quand même pour faire des tests vite fait (vous corrigerez le problème plus tard ^^).

Facile:

PYTHONPATH='/home/sam/un_dossier_qui_contient_mes_libs:/home/sam/projects/autre_projet'
export $PYTHONPATH

Et voilà, tout ce qui est dans ces deux dossiers est importable.

Il y a encore :

PYTHONHOME : choisir un autre dossier dans lequel chercher l’interpréteur Python.
PYTHONCASEOK : ingorer la casse dans le nom des modules sous Windows
PYTHONIOENCODING : forcer un encoding par défaut pour stdin/stdout/stderr
PYTHONHASHSEED : changer la seed hash() (renforce la sécurité de la VM)

Variables d’environnement permanentes

Les programmes Python utilisent beaucoup les variables d’environnement : Django, Celery, nose, virtualenv, pip… Tous peuvent être aussi configurés avec ces variables.

Parfois, on voudra que cette variable soit accessible depuis tous les shells, et même après le reboot. Bref, rendre la configuration permanente.

Il y a plusieurs solutions. L’une est de mettre la déclaration de la variable dans le script de démarrage de votre shell, par exemple sous bash, de mettre la variable dans .bashrc.

Ainsi, j’ai des entrées comme celle-ci dans mon .bashrc :

# évite à pip de télécharger plusieurs fois la même lib à la réinstallation
PIP_DOWNLOAD_CACHE='/opt/pip-cache';
export PIP_DOWNLOAD_CACHE;

Une autre est de la mettre dans un hook, c’est à dire un script exécuté à un moment donné par un programme. De nombreux programmes ont des hooks, et il y a des exemples sur le blog pour virtualenv et git.

Variables d’environnement personnalisées

Vos propres programmes peuvent lire (pour se configurer) et écrire (pour configurer d’autres programme ou forcer leur propre configuration en cas de multiprocessing) des variables d’environnement. Il suffit de faire :

>>> import os
>>> os.environ
{'LC_NUMERIC': 'fr_FR.UTF-8', 'gs_max_changes': '99', 'scmbDir': '/home/sam/.scm_breeze', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'AUTOJUMP_DATA_DIR': '/home/sam/.local/share/autojump', 'LC_IDENTIFICATION': 'fr_FR.UTF-8', 'XDG_CURRENT_DESKTOP': 'Unity', 'GNOME_KEYRING_PID': '2787', 'LOGNAME': 'sam', 'USER': 'sam', 'PROMPT_COMMAND': 'set_bash_prompt;preexec_invoke_cmd', 'PATH': '/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games', 'LC_PAPER': 'fr_FR.UTF-8', 'GNOME_KEYRING_CONTROL': '/home/sam/.cache/keyring-1rkOf1', 'design_av_dirs': 'Animations Videos Flash Music Samples', 'DISPLAY': ':0', 'SSH_AGENT_PID': '2849', 'LANG': 'fr_FR.UTF-8', 'TERM': 'xterm', 'SHELL': '/bin/bash', 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0', 'XDG_SESSION_COOKIE': 'ccef8e8a757563a3c14c304f00000003-1375177738.724796-1812587231', 'LANGUAGE': 'fr_FR:fr_CA:en', 'SESSION_MANAGER': 'local/sam:@/tmp/.ICE-unix/2798,unix/sam:/tmp/.ICE-unix/2798', 'LC_MONETARY': 'fr_FR.UTF-8', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-4sjzHNl8JS,guid=6ea6a72c49faf1630800018', 'VIRTUALENVWRAPPER_LOG_DIR': '/home/sam/.virtualenvs', 'COMPIZ_CONFIG_PROFILE': 'ubuntu', 'EDITOR': '/usr/bin/textadept', 'DESKTOP_AUTOSTART_ID': '10b40d4ebf3d1cf3fd700000027980010', 'GPG_AGENT_INFO': '/home/sam/.cache/keyring-1rkOf1/gpg:0:1', 'HOME': '/home/sam', 'WORKON_HOME': '/home/sam/.virtualenvs', 'SHLVL': '1', 'SSH_AUTH_SOCK': '/home/sam/.cache/keyring-1rkOf1/ssh', 'VIRTUALENVWRAPPER_HOOK_DIR': '/home/sam/.virtualenvs', 'LC_ADDRESS': 'fr_FR.UTF-8', 'COMP_WORDBREAKS': ' \t\n"\'><;|&(:', 'root_design_dir': '/home/sam/Dropbox/Design', 'GDMSESSION': 'ubuntu', 'project_design_dir': 'design_assets', 'git_status_command': 'git_status_shortcuts', 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0', 'LC_ALL': 'fr_FR.UTF-8', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'git_env_char': 'e', '_': '/usr/bin/python', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'VIRTUALENVWRAPPER_PROJECT_FILENAME': '.project', 'DESKTOP_SESSION': 'ubuntu', 'GIT_REPO_DIR': '/home/sam/Work', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/etc/xdg', 'GTK_MODULES': 'canberra-gtk-module:canberra-gtk-module', 'UBUNTU_MENUPROXY': 'libappmenu.so', 'AUTOJUMP_HOME': '/home/sam', 'LC_TELEPHONE': 'fr_FR.UTF-8', 'XAUTHORITY': '/home/sam/.Xauthority', 'LC_MEASUREMENT': 'fr_FR.UTF-8', 'PWD': '/home/sam', 'PIP_DOWNLOAD_CACHE': '/opt/pip-cache', 'design_ext_dirs': 'Fonts IconSets', 'ga_auto_remove': 'yes', 'LC_NAME': 'fr_FR.UTF-8', 'design_base_dirs': 'Images Backgrounds Logos Icons Mockups Screenshots', 'LC_TIME': 'fr_FR.UTF-8', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'XDG_DATA_DIRS': '/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/', 'GIT_REPOS': ''}

C’est un simple dico dans lequel vous pouvez lire et écrire. Comme vous pouvez le voir, il ne s’agit pas juste des variables qui concernent Python mais de toutes celle de la session, donc attention, de grands pouvoirs impliquent de grandes possibilités de merder.

]]>
http://sametmax.com/variables-denvironnement-utilisees-par-python/feed/ 9
Historique bash récent 8 http://sametmax.com/historique-bash-recent/ http://sametmax.com/historique-bash-recent/#comments Thu, 11 Apr 2013 12:23:52 +0000 http://sametmax.com/?p=5683 PyDanny en affichant ici mon historique des commandes les plus utilisées.]]> Je plagie PyDanny en affichant ici mon historique des commandes les plus utilisées récupéré grâce à :

$ history | awk '{a[$2]++ } END{for(i in a){print a[i] " " i}}'|sort -rn |head -n 20

L’exercice consiste à commenter chaque entrée, donc acte :

100 ./manage.py # Jamie Foxx
71 sudo         # Make me a sandwich (then apt-get upgrade)
56 cd           # j'ai beaucoup de projets différents
41 ipython      # Voilà ce que c'est d'être dev Python...
40 ssh          # ... sur des projets Web
37 py.test      # Ben oui, je fais des tests !
37 ls           # Comment ça IOError ?
34 gs           # Alias de Git status :-)
26 ga           # Merveilleux SCMBreeze, installez le
24 pip          # requests, ipdb, path.py, peewee...
24 co           # git commit -m "`echo "$*" | sed -e 's/^./\U&\E/g'`"
22 vi           # Presque que pour les config d'nginx
21 python       # Quand je fais des tests pour le blog
17 [censored]   # Le nom d'un projet de site de Cul
15 workon       # Ca devrait être + élévé, mais j'ai ajouté l'autovirtualenv 
15 grin         # J'aime pas "rechercher dans tous les fichiers" sur ST2
11 tail         # Une longue session de debuggage via log d'erreurs
10 ipython3     # Migration vers Python 3 en cours
9 wget          # Pas envie de toucher ma souris
]]>
http://sametmax.com/historique-bash-recent/feed/ 8
Invalid cross-device link 3 http://sametmax.com/invalid-cross-device-link/ http://sametmax.com/invalid-cross-device-link/#comments Tue, 09 Apr 2013 10:19:57 +0000 http://sametmax.com/?p=5652 Les erreurs d’upload de fichier, c’est 99% de problèmes de droit d’accès et d’espace disque. Mais de temps à autres, on tombe sur des petites saloperies bien vicelardes comme ce code anodin :

os.rename(uploaded_tmp_file, destination)

Ce snippet, comme vous l’aurez compris, prend simplement un fichier qui vient d’être uploadé et le déplace vers un autre dossier où il sera traité, chouchouté, encodé, et mis en ligne.

Sauf que la ligne en question nous a valu un cryptique :

IOError: Invalid cross-device link

PDB nous confirme le merdier, même en le faisant à la main. Pourtant la commande bash MV fait le déplacement du fichier sans problème.

User / group ? Checked.

Permission en lecture écriture ? Checked.

SEL linux ? Désactivé depuis longtemps.

Quid alors ?

Les archives de la mailling list de Python nous offre une réponse à la question, que je vous traduis :

mv est un programme étonnamment complexe, tandis que os.rename est un wrapper autour de rename(2) qui est probablement documenté sur ton système comme retournant EXDEV dans ces circonstances.

os.xxx est généralement une surcouche assez fine autour de ce que ton OS fournit, et en hérite toutes les limites. Pour certains actions, os.shutil fournit quelque chose qui se situe entre os.xxx et os.system(“xxx”) en terme de complexité et de capacité.

Je l’ai traduis en français, maintenant je vous la refais en langage humain : os.rename ne fait vaguement qu’appeler la commande rename, qui n’est pas très puissante, et notamment qui est incapable de gérer un déplacement de fichier d’une partition à une autre. Or dans notre cas, notre dossier temporaire était sur une partition séparée pour des raisons de perfs.

La solution est d’utiliser shutil, un module un peu plus lent, mais surtout de plus haut niveau qui se charge des détails comme la nature et l’origine du fichier et de sa destination.

Bref, la solution est tout simplement de faire :

shutil.move(uploaded_tmp_file, destination)

Tout ça pour ça, oui, mais c’est ce qui arrive quand une abstraction ne fait plus son boulot dans un langage de haut niveau où on a l’habitude que tout soit automatisé.

]]>
http://sametmax.com/invalid-cross-device-link/feed/ 3
Set -e for the win 7 http://sametmax.com/set-e-for-the-win/ http://sametmax.com/set-e-for-the-win/#comments Thu, 14 Mar 2013 08:26:52 +0000 http://sametmax.com/?p=5408 10 ans plus tard, je découvre cette option pour les scripts bash.

Voyez vous, quand on écrit un script bash, il exécute les commandes ligne à ligne. Si il y en a une qui retourne une erreur, il continue vaillamment.

Sur un script où chaque ligne dépend de la précédente (comme un script de déploiement), c’est moyen.

Pour y pallier, il suffit de mettre tout en haut du script :

set -e

Et voilà. Si une commande retourne une erreur, le script s’arrête à ce niveau. 10 ans de Linux et je découvre ça maintenant. Moi content.

]]>
http://sametmax.com/set-e-for-the-win/feed/ 7
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
Un alias bash pour Django + virtualenv dont je ne peux plus me passer 9 http://sametmax.com/un-alias-bash-pour-django-virtualenv-dont-je-ne-peux-plus-me-passer/ http://sametmax.com/un-alias-bash-pour-django-virtualenv-dont-je-ne-peux-plus-me-passer/#comments Wed, 10 Oct 2012 13:57:03 +0000 http://sametmax.com/?p=2544 Ce n’est pas subtil, ça veut dire que pour chaque projet on rajoute cette patate dans son .bashrc:

function nom_du_projet {
    workon nom_du_virtualenv;
    cd /chemin/vers/le/projet/django/;
    if [[ $# -ne 0 ]]; then
        ./manage.py $@
    fi
}

Mais du coup:

Aller dans le dossier du projet et activer le virtualenv:

nom_du_projet

Aller dans le dossier du projet et activer le virtualenv, et éxécuter une commande de manage.py:

nom_du_projet schemamigration app --auto

Et bien sur on peut toujours revenir dans le dossier précédent avec:

cd -

]]>
http://sametmax.com/un-alias-bash-pour-django-virtualenv-dont-je-ne-peux-plus-me-passer/feed/ 9
Liste des partitions, de leur type, de la place restante sous Linux – df / du 14 http://sametmax.com/liste-des-partitions-de-leur-type-de-la-place-restante-sous-linux-df-du/ http://sametmax.com/liste-des-partitions-de-leur-type-de-la-place-restante-sous-linux-df-du/#comments Mon, 10 Sep 2012 01:36:48 +0000 http://sametmax.com/?p=2049 Quelques commandes sympa sous Linux pour connaître les ressources disque de son serveur.

la commande df:
Retourne l’espace disque utilisé par chaque partition montée sur votre machine.

-h Affiche les résultats sous forme humainement lisible :)
-T indique le type de système de fichiers utilisé

df -hT
Sys. fich.    Type  Taille  Uti. Disp. Uti% Monté sur
/dev/sda2      xfs     20G  2,9G   17G  15% /
tmpfs        tmpfs    3,9G     0  3,9G   0% /dev/shm
/dev/sda1      xfs    192M   28M  164M  15% /boot
/dev/sda4      xfs    1,8T  220G  1,6T  12% /data

la commande du:
Retourne l’espace disque utilisé par un répertoire

-h Affiche les résultats sous forme humainement lisible :)
-s affiche la somme des fichiers du répertoire

du -hs /boot/
18M	/boot/

Et si vous voulez trouver ce qui prend toute cette place, c’est par ici.

Edit:
Pour le côté prog on peu utiliser psutil en python qui permet tout un tas d’acceès aux infos de la machine.
Merci François

]]>
http://sametmax.com/liste-des-partitions-de-leur-type-de-la-place-restante-sous-linux-df-du/feed/ 14
SCM Breeze facilite la selection de vos fichiers à commiter sous Git 11 http://sametmax.com/scm-breeze-facilite-la-selection-de-vos-fichiers-a-commiter-sous-git-avec/ http://sametmax.com/scm-breeze-facilite-la-selection-de-vos-fichiers-a-commiter-sous-git-avec/#comments Fri, 31 Aug 2012 14:51:39 +0000 http://sametmax.com/?p=1946 git add . comme Max des gros bourrins. Mais je vais partir du principe que certains d'entre vous font leurs commits avec amour, en prenant uniquement les fichiers dont ils ont besoin.]]> Je sais, vous faites tous git add . comme Max des gros bourrins. Mais je vais partir du principe que certains d’entre vous font leurs commits avec amour, en prenant uniquement les fichiers dont ils ont besoin.

Et ces certains-d-entre-vous-qui-font-leurs-commits-avec-amour sont frustrés de devoir manuellement ajouter chaque fichier ou dossier.

Ceci est un message d’espoir pour notre minorité bafouée aux cris étouffés par la répression grondante des… Mais je m’égare.

La révolution s’appelle SCM Breeze, camarade

Ca s’installe les doigts dans le goulag:

git clone git://github.com/ndbroadbent/scm_breeze.git ~/.scm_breeze

Et on rajoute ça dans le .bashrc:

[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] && source "$HOME/.scm_breeze/scm_breeze.sh"

Puis on copie git.scmbrc.example dans ~/.git.scmbrc:

cp ~./.scm_breeze/git.scmbrc.example ~/.git.scmbrc

Et on a alors accès à la commande gs, qui donne à peu prêt ça (shameless hotlinking):

En plus d’être vachement court à taper et d’avoir une sortie plus lisible, on obtient des pitis numéros a gauche (évidément). Et là, on peut faire des trucs vachement révolutionnaires comme:

ga 3 9 11 # rajoute uniquement ces fichiers pour les faire commiter
ga 3..9 # rajoute les fichiers de 3 à 9 pour les commiter
grm 3 # retire ce fichier
grs 5 # soft reset sur le fichier

Mais il y a encore mieux. Si vous connaissez autojump, vous apprecierez git_index, livré par le parti avec SCM Breeze:

Un petit alias dans .bashrc:

alias c="git_index"

Et à chaque fois qu’on rajoute un nouveau repo:

c --rebuild

Après il suffit de faire:

c quelques_lettre_du_nom_du_repo

Et où qu’on soit dans le système, on se retrouve dans le repo.

Vous pouvez en apprendre plus sur github.

PS: ouai, c’est du ruby…

]]>
http://sametmax.com/scm-breeze-facilite-la-selection-de-vos-fichiers-a-commiter-sous-git-avec/feed/ 11