jeudi 26 février 2009

Effectuer une compie de synchronisation

La commande rsync permet d'effectuer une copie de synchronisation sous Linux. Cette commande permet notamment d'effectuer des backup de vos données (Musique, films, images etc.) mais elle peut également servir à synchroniser les codes sources de vos programmes sans utiliser de gestionnaire de configuration.

Il existe de nombreuses options que l'on peut consulter à l'aide de man.


Exemples :

Copie d'une arborescence entière :

rsync -rvu /srcdir /dstdir


Cette commande permet de copier les fichiers et leur arborescence de /srcdir vers /dstdir
-r pour récursif
-v pour verbose
-u pour update (Autrement les fichiers qui n'ont pas été modifié sont recopiés)

L'option -n permet de simuler l'opération en listant les modifications qui seront effectuées.

Copie des fichiers L* et leur arborescence dans vers /dstdir :


rsync -rvu -f"+ */" -f"+ L*" -f"- *" /srcdir /dstdir

Pour copier la structure de repértoire seulement

rsync -av --include='*/' --exclude='*' src dest

Pour synchroniser un projet maven à partir d'un code source modifié sur une machine n'ayant pas accès au gestionnaire de configuration.

rsync -rnvu --delete -c --exclude=.svn --exclude=target/ /elsewhere/mydistantproject/ /home/myworkspace/mylocalproject/

Convertir des fichiers stéréo en mono

Le logiciel sox sous linux permet d'effectuer une conversion de stéréo vers mono.
Il permet également de doser le mixage.
Pour ne recopier que le canal gauche
sox -c1 input.mp3 output.mp3 remix 1

Pour ne recopier que le canal droit
sox -c1 input.mp3 output.mp3 remix 2

Pour transformer en mono
sox -c1 input.mp3 output.mp3 remix -


Pour effectuer le transformation de manière globale.

find *.mp3 -exec sox -c1 '{}' 'left/{}' remix - \;

mercredi 25 février 2009

Comment parcourir récursivement un répertoire pour appliquer des traitement en C

Lorsque l'on veut appliquer un traitement à des fichiers en parcourant l'arborescence. Il y a la possibilité d'utiliser la commande find associé à - exec.

Voici quelques exemples du monde réel world FIND usage


Copie dans un répertoire
find / -type f -name *.jpg -exec cp {} . \;
find /home/hudson/repertoire-data/ -type f -regex ".*ARTICLE_O.*" -exec echo {} \;
find /home/hudson/repertoire-data/ -type f -regex ".*ARTICLE_[^O].*" -exec echo {} \;
find . -type f -size +10000 -exec ls -al {} \;
Récherche des fichiers accédés il y a un jour
find . -atime +1 -type f -exec mv {} TMP \;
find . -name "-F" -exec rm {} \; # a script error created a file called -F
find . -exec grep -i "vds admin" {} \;
find . \! -name "*.Z" -exec compress -f {} \;
find . -type f \! -name "*.Z" \! -name ".comment" -print | tee -a /tmp/list
find . -exec chmod 775 {} \;
find . -user xuser1 -exec chown -R user2 {} \;
find . -exec grep PW0 {} \;
find . -exec grep -i "pw0" {} \;
find . -atime +6
find . -atime +6 -exec ll | more
find . -atime +6 -exec ll | more \;
find . -name auth*
find . -exec grep -i plotme10 {} \;
find . -ls -exec grep 'PLOT_FORMAT 22' {} \;
find . -print -exec grep 'PLOT_FORMAT 22' {} \;
find . -print -exec grep 'PLOT_FORMAT' {} \;
find . -print -exec grep 'PLOT_FORMAT' {} \;
find ./machbook -exec chown 184 {} \;
find . \! -name '*.Z' -exec compress {} \;
find . \! -name "*.Z" -exec compress -f {} \;
find /raid/03c/ecn -xdev -type f -print
find /raid/03c/ecn -xdev -path -type f -print
find / -name .ssh* -print | tee -a ssh-stuff
find . -name "*font*"
find . -name hpmcad*
find . -name *fnt*
find . -name hp_mcad* -print
find . -grep Pld {} \;
find . -exec grep Pld {} \;
find . -exec grep Pld {} \;
find . -exec grep PENWIDTH {} \; | more
find . -name config.pro
find /raid -type d -name ".local_sd_customize" -print
find /raid -type d -name ".local_sd_customize" -ok cp /raid/04d/MCAD-apps/I_Custom/SD_custom/site_sd_customize/user_filer_project_dirs {} \;
find /raid -type d -name ".local_sd_customize" -exec cp /raid/04d/MCAD-apps/I_Custom/SD_custom/site_sd_customize/user_filer_project_dirs {} \;
find . -name xeroxrelease
find . -exec grep xeroxrelease {} \;
find . -name xeroxrelease
find . -name xeroxrelease* -print 2>/dev/null
find . -name "*release*" 2>/dev/null
find / -name "*xerox*" 2>/dev/null
find . -exec grep -i xeroxrelease {} \;
find . -print -exec grep -i xeroxrelease {} \;
find . -print -exec grep -i xeroxrelease {} \; > xeroxrel.lis
find . -exec grep -i xeroxrel {} \;
find . -print -exec grep -i xeroxrel {} \;
find . -print -exec grep -i xeroxrel {} \; | more
find /raid/03c/inwork -xdev -type f -print >> /raid/04d/user_scripts/prt_list.tmp
find . -exec grep '31.53' {} \;
find . -ls -exec grep "31/.53" {} \; > this.lis
find . -print -exec grep "31/.53" {} \; > this.lis
find . -print -exec grep 31.53 {} \; > this.lis
find . -exec grep -i pen {} /;
find . -exec grep -i pen {} \;
find . -print -exec grep -i pen {} \; | more
find . -exec grep -i pen {} \;
find . -atime +6 -exec ll | more \;
find . -atime +6 -exec ll \;
find . -atime +6 -exec ls \;
find . -atime +30 -exec ls \;
find . -atime +30 -exec ls \; | wc -l
find . \! -name '*.Z' -exec compress -f {} \;
find . -name 'cache*' -depth -exec rm {} \;
find . -name 'cache*' -depth -print | tee -a /tmp/cachefiles
find . -name 'cache[0-9][0-9]*' -depth -print | tee -a /tmp/cachefiles
find . -name 'hp_catfile' 'hp_catlock' -depth -print | tee -a /tmp/hp.cats
find . -name 'hp_catfile' -name 'hp_catlock' -depth -print | tee -a /tmp/hp.cats
find . -name 'hp_cat*' -depth -print | tee -a /tmp/hp.cats
find . -name 'hp_cat[fl]*' -depth -print | tee -a /tmp/hp.cats
find /raid -name 'hp_cat[fl]*' -depth -print
find . \! -name '*.Z' -exec compress -f {} \;
find . -name '*' -exec compress -f {} \;
find . -xdev -name "wshp1*" -print
find . -xdev -name "wagoneer*" -print
find . -name "xcmd" -depth -print
find /usr/contrib/src -name "xcmd" -depth -print
find /raid -type d -name ".local_sd_customize" -exec ls {} \;
find /raid -type d -name ".local_sd_customize" \
-exec cp /raid/04d/MCAD-apps/I_Custom/SD_custom/site_sd_customize/user_filer_project_dirs {} \;



L'inconvénient de la méthode find est qu'elle passe par l'interpréteur de commande pour lancer le shell ce qui peut-être problématique lorsque l'on souhaite traiter des fichiers ayant des noms comportant des espaces, guillemets, parenthèse etc.

La seconde solution est de faire un programme C pour appliquer son traitement. La librairie ftw adresse spécialement ce type de problème, elle fonctionne comme la commande find.

Ses paramètres sont
* Le chemin de départ de la récursion
* La méthode à appeler pour chaque élement (Le nom peut varier mais elle doit retourner un entier et avoir trois arguments.
int nomdemethode(const char *path, const struct stat *ptr, int flag))

Voici un exemple :

#include <ftw.h>
#include <stdio.h>

int process(const char *path, const struct stat *ptr, int flag)
{
printf("Found\n path:%s\nflag%d\n", path, flag);
return 0;
}

int main(int argc, char *argv[]) {
if(argc == 1){
ftw(".", process, 1);
}
else{
ftw(argv[1], process, 1);
}
return 0;
}


Exemple d'utilisation :

Je voulais appliquer un traitement audio à de nombreux fichiers par le biais de la commande sox, malheureusement ce programme n'avait pas de fonction qui permettait d'effectuer des traitements par lots.

Les noms de fichiers comportaient aussi de nombreux caractères spéciaux qui empêchaient l'utilisation de la commande find. J'ai adapté le source du programme.

- Renommer la méthode main de sox par une méthode ancienmain
- Utiliser la méthode main du type présenté plus haut
- Créer une méthode appelée à chaque fois que ftw rencontre un nouvel élément on l'appelle process.

int process(char *dirname, const struct stat *status, int type){
if(!(type == FTW_F && strstr(dirname,".mp3")!=NULL&& strstr(dirname,"/L-")==NULL)){
return 0;
}

// Ici nous construisons les paramètres qui servent pour appeler l'ancien main.


char * params[6];
char nom_transforme[200];
struct stat s;
nom_transforme[0]=0;
params[0]="sox";
params[1]="-c1";
// ...
params[4]="remix";
params[5]="1";

/*
Les programmes ne sont généralement pas fait pour fonctionner en batch
aussi, il est nécessaire d'initialiser les variable globale à chaque appel.
Ce sont celle qui sont en dehors de toute méthode.
**/
mavarglobale1=0;
mavarglobale2=1;
...
mavarglobale3 = NULL;
mavarglobale4 = 0;

// Appel de l'ancien main
ancienmain(6,params);
}


Il ne s'agit clairement pas d'un controunement facile, et la volumétrie des fichiers doit clairement compenser l'effort de programmation par rapport à un appel de find.

Montage Samba Mandriva

Comment monter un partage samba en ligne de commande sous mandriva.

Installer le rpm mount-cifs

taper
mount.cifs //Monserver/monpartage /mnt/monpointdemontage -ouser=monuser

vendredi 20 février 2009

Utilisations des threads

Il existe deux techniques d'utilisation des thread en JAVA :

* Implémenter l'interface Runnable
* Etendre la classe thread.

Dans l'optique de faire un code robuste, je recommande d'implémenter l'interface Runnable, elle évite de se perdre dans la profusion de méthodes offertes par la classe Thread.

Les threads servent à paralléliser les tâches. Deux opérations clés sont importantes.

* Le départ
* La synchronisation (jointure)

Le plus délicat est de comprendre l'utilisation du wait et du notify. Pour être utilisé le wait et le notify doivent être placé sur la même classe (Ici le ThreadGroup)


Ce bloc lance 25 threads

// Ici nous construisons sans les déclencher tous les thread dont nous avons besoins
List<thread> threads = new ArrayList<thread>();
ThreadGroup threadGroup = new ThreadGroup("MyThreadList");
for (int i = 0; i < thread =" new" thread =" new"> 0) {
System.out.println("Threads restants : " + threadGroup.activeCount());
// Attente d'une nçotification
threadGroup.wait();
}
}



Voici l'implémentation de Runnable


public class MyThread implements Runnable {

public MyThread(ThreadGroup tg) {
threadGroup = tg;
}

public void run() {
System.out.prinln("Effectue le traitement");

// Ici le ThreadGroup est notifié
synchronized (threadGroup) {
// Notification du parent
threadGroup.notify();
}
}

jeudi 19 février 2009

Encodage et maven

Si l'on assemble les projets maven sur des machines ayant des encoding différents (par exemple une application développée sous windows et assemblé sur LINUX UTF-8), il peut y avoir des problèmes d'encodage de fichier se manifestant par caractères inconnu aparaissant à l'écran.

Pour ne pas avoir de soucis, il est nécessaire de préciser l'encoding du compilateur et celui de l'assembleur ressources dans le descipteur de projet pom.xml .

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>ISO-8859-1</encoding>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin
</artifactId>
<configuration>
<encoding>ISO-8859-1</encoding>
</configuration>
</plugin>