Humus numericus

Aller au contenu | Aller au menu | Aller à la recherche

R, Spip et autres

Mot-clé - script

Fil des billets

mardi 25 novembre 2008

Quelles belles courbes !

Que voilà :

Munin postfix mailqueue

C'est quoi donc ? C'est le nombre de mails contenus dans la file d'attente du postfix de ce serveur... La jolie courbe bleue qui monte qui monte ce sont les 15000 mails reçus dans la nuit de dimanche à lundi suite à un envoi massif de spams depuis un autre serveur qui ne m'appartient pas mais dont je reçois les mails d'admin. Les 15000 mais sont tous les Undelivered mail returned to sender résultant de cet envoi de spams.

Bon ben tout ça n'a pas plu à mon postfix, mais surtout à mon dspam, qui a régulièrement lâché après les différentes relances effectuées dans la journée. Ça n'est que dans la soirée que j'ai vraiment pu m'occuper du problème (Lles jolies courbes verrtes sur la figure), surveiller dspam et le relancer lorsqu'il plantait. Mais vu le débit (pas plus d'un mail à la seconde, pas sûr que mon installation soit bien optimisée), j'en avais pour un moment.

Heureusement, j'ai pu trouver un petit script permettant de supprimer des mails de la file d'attente à partir d'un regexp sur le résultat de postqueue -p. Résultat, le script suivant :

while true; do for i in $( sudo postqueue -p |head -n 500 | grep -i mail |awk '{print $1}'|sed s/\*// );do sudo postsuper -d $i; done; done

m'a permis de terminer l'évacuation du bouchon vers 2h du matin, au lieu de beaucoup plus tard...

jeudi 6 décembre 2007

Script shell de transfert de photos

Pas sûr que ça en vaille la peine, mais je me permets quand même de mettre en ligne le petit script bash que j'utilise pour transférer les photos depuis mon appareil numérique vers mon PC. Le script en question part du principe que l'appareil est reconnu comme un périphérique de stockage de masse USB et qu'il est automatiquement monté au point de montage indiqué par la variable mount_point. Il faut également renseigner les variable source_dir (chemin vers le répertoire dans lequel se trouve les photos à partir du point de montage) et cible_dir (emplacement des photos sur le PC). Vous aurez également besoin du paquet libjpeg-progs pour avoir la commande exifautotran.

Une fois que vous avez tout ça, vous aurez juste à brancher votre appareil et à lancer le script. Celui-ci s'occupera de monter le périphérique, de copier chaque image dans un répertoire nommé selon la date de prise de la photo (au format /home/photos/2007/12 par exemple) et d'effectuer une rotation en fonction de l'orientation horizontale ou verticale contenue dans les données EXIF.

#!/bin/sh                                                           
                                                                    
mount_point=/mnt/photo
source_dir=dcim/100km028 
cible_dir=/home/photos

mount $mount_point
for i in $mount_point/$source_dir/*.jpg; do  
        img=`basename $i`
        annee=`stat -c %y $i | cut -d '-' -f 1`
        mois=`stat -c %y $i | cut -d '-' -f 2`
        cible=$cible_dir/$annee/$mois
        if [ ! -d $cible ];
        then
                mkdir -p $cible
        fi      
        echo "Copie de $i vers $cible/$img"
        cp -i $i $cible/$img
        exifautotran $cible/$img
done;   
sleep 2s
umount $mount_point

Comme d'hab en ces lieux, vous constaterez que c'est du vite fait !

jeudi 24 août 2006

Comparaison d'un script simple en Perl, Python et Ruby

Tiens, suite à une question d'un collègue de boulot aujourd'hui, je me suis amusé à comparer la manière de faire une tâche assez simple dans trois langages de script différents. L'objectif est d'afficher le chemin complet de tous les répertoires contenus (récursivement) dans un répertoire donné (en l'occurrence /var/log). Je trouve le résultat assez représentatif des particularités des différents langages :

En Python

import os
from os.path import join
for root, dirs, files in os.walk('/var/log'):
    for name in dirs:
        print join(root, name)

C'est pas forcément super intuitif (faut comprendre que la fonction os.walk renvoit un tuple avec le répertoire racine, les répertoires contenus et les fichiers contenus de chaque sous-répertoire parcouru. Mais c'est assez efficace.

En Perl

use File::Find;
find sub { print $File::Find::name, "
" if -d } , '/var/log';

Ah bah c'est sûr, difficile de faire plus bref. Mais c'est pas forcément évident du premier coup d'oeil, entre l'utilisation d'une référence à une fonction en argument de find, ou celui du test -d.

En Ruby

require 'find'
Find.find('/var/log') { |path| puts path if File.directory?(path) }

Et voilà. Simple, lisible, compact, compréhensible (du moins si on a compris le concept de bloc et d'itérateur). En un mot : é-lé-gant.

Bon, allez, je suis pas tout à fait objectif, je vous l'accorde...

mercredi 5 avril 2006

Textile mode

Youpi, youpla, je viens de créer mon premier major mode pour Emacs. C'est un mode visant à faciliter l'écriture de document suivant la syntaxe de balisage Textile.

Pour l'instant il ne fait pas grand-chose, c'est à dire seulement de la coloration syntaxique, et il est en version vraiment alpha, pas plus testée que ça. N'hésitez pas à me faire remonter tout bug ou commentaire.

La dernière version du script peut être téléchargée là :

http://svn.nozav.org/scripts/elisp/textile-mode/textile-mode.el

Pour plus d'informations sur Textile, vous pouvez consulter :

samedi 7 janvier 2006

erc2html

Je viens de pondre un tout petit script en Ruby qui me permet de transformer un log de discussion IRC enregistré sous ERC (Emacs Relay Chat) en fichier HTML pour publication. Le script supprime les sauts de ligne superflus, supprime les messages serveur et colorise deux trois bricoles. C'est loin d'être parfait, mais si ça peut être utile à quelqu'un...

require "cgi"

str = IO.read("/home/julien/lautre_20060107.log.txt")

titre = "Titre de la page"
charset = "UTF-8"

head = <<EOL
<html>
<head>
<title>#{titre}</title>
<meta http-equiv="Content-Type" content="text/html; charset=#{charset}" />
<style type="text/css">
 * {font-family: monospace;}
 .nick {font-weight: bold; color: #A00;}
 .ref {font-style: italic; color: #090;}
 .timestamp {color: #AAA;}
 .me {color: #00B;}
</style>
</head>
<body>
<h1>#{titre}</h1>
<p>
EOL

foot = <<EOL
</p>
</body>
</html>
EOL

str.gsub!(/^ERC>.*$/n, "")
str.gsub!(/
\s+/n, " ")
str.gsub!(/[\d\d:\d\d]/) { |s| "
"+s+"
"}
str.gsub!(/\s+$/n, "")
str.gsub!(/^\*\*\* .*$/n, "")
5.times {str.gsub!(/
\s*
/n, "
")}

str = CGI::escapeHTML(str)
str.gsub!(/^&lt;.*?&gt;/n) {|s| '<span class="nick">'+s+'</span>'}
str.gsub!(/(<\/span>) (\w+\s?:)/n) {|s| $1+' <span class="ref">'+$2+'</span>'}
str.gsub!(/[\d\d:\d\d]/) { |s| '<span class="timestamp">'+s+'</span>'}
str.gsub!(/^\* .*$/n) {|s| '<span class="me">'+s+'</span>'}
str.gsub!(/
/, "<br />
")

str = head + str
str = str + foot

puts str

lundi 14 novembre 2005

Oneliner en Ruby

Après avoir essayé (de manière plus ou moins approfondie) plusieurs langages de script comme Perl ou Python, et après avoir longuement hésité, je crois que mon choix va finalement se porter sur Ruby. Celui-ci me semble en effet combiner à la fois la puissance et la concision de Perl avec la clarté d'un langage purement objet.

Voici donc un exemple de oneliner en Ruby, en l'occurrence qui permet de renommer en minuscules tous les fichiers d'un répertoire :

 ruby -e 'ARGV.each {|file| File.rename(file, file.downcase)}' *

Plutôt simple, non ? En plus, il y a moyen de rendre cela beaucoup plus souple et puissant en utilisant des regexps, du type :

 ruby -e 'ARGV.each {|file| File.rename(file, file.gsub(/toto/, "titi")}' *

vendredi 13 mai 2005

Conversion en lot de fichiers WMA en fichiers OGG

Il m'arrive régulièrement de recevoir une série de fichiers audio au format WMA de Windows Media. Mplayer sait les lire, certes, mais quoi de mieux qu'un format audio libre et ouvert comme Ogg Vorbis pour assurer la pérennité de ses musiques préférées ?

Heureusement, grâce à mplayer toujours et à une astuce vue sur linuxfr, voici un petit script shell qui vous permet de convertir en lot tous les fichiers wma d'un répertoire en ogg. Notez que vous pouvez facilement l'utiliser pour effectuer une conversion en mp3, en utilisant lame plutôt que oggenc (mais le format mp3 n'est pas libre) :

#!/bin/sh

for WMA in `ls *.wma`; do
    OGG=`basename $WMA .wma`.ogg;
    TMP=${TMPDIR:-/tmp}/wma2ogg.$$
    mplayer -ao pcm:file=$TMP $WMA;
    trap "rm $TMP* 2>/dev/null" 0
    nice -n 15 oggenc -m 128 $TMP -o $OGG
done

Seul petit hic, ce script peut ne pas fonctionner si les noms de vos fichiers contiennent des espaces. Vous pouvez donc utiliser la commande suivante pour transformer tous les espaces des noms de fichiers de votre répertoire en underscores :

find . -type f -name "* *" -print0 | \
perl -n0e '$old = $_; s/ /_/g; rename $old, $_'

De même, ce script utilise les options de la dernière version de mplayer. Si vous rencontrez des problèmes, vous pouvez essayer la syntaxe suivante :

mplayer -ao pcm -aofile $TMP $WMA;

jeudi 12 mai 2005

Changer récursivement les permissions de répertoires

Il peut parfois être utile de changer d'un coup les permissions ou les propriétés d'un répertoire et de ses sous-répertoires, mais seulement des répertoires, pas des fichiers normaux.

Deux exemples pratiques :

  1. vous venez de transférer des fichiers depuis une parto windows, et ceux-ci ont tous la permission "éxecutable". Seulement, si vous faites un chmod -R -x *, vos répertoires vont perdre leur attribut exécutable et vous ne pourrez plus rentrer dedans. C'est gênant ;
  2. vous avez un répertoire (par exemple /var/www) que vous voulez partager entre plusieurs personnes d'un même groupe (par exemple le groupe web). L'idéal est de positionner le "sticky bit" de ce répertoire et de ses sous-répertoire pour le groupe, afin que tous les fichiers nouvellement créés appartiennent également à ce groupe. Là aussi, un chmod -R g+s * pose problème.

Voilà donc la solution à ces deux problèmes. Il suffit de se positionner dans le répertoire racine choisi et de faire un :

find . -type d | xargs chmod +x

ou, pour le deuxième problème :

find . -type d | xargs chmod g+s

Et voilou !