# [débat] Quel langage pour les "quick-hacks" ?

## anigel

<trip=médiéval>

Oyez, oyez, braves contributeurs du forum Gentoo français,

Le printemps vient de naître, et voici venir le nouveau débat. Ce dernier fera cette fois l'objet d'une discussion que nous espérons éminemment constructive, et dans laquelle les preux chevaliers qui auront le courage de concourir pourront exposer, non seulement leurs arguments, mais aussi des exemples concrets d'applications, sous formes de scripts, de fichiers .profile, ou autres formes qu'ils jugeront utiles.

Les quick-hacks, keskecé ? Ben en fait c'est tout ce qui ressemble de près ou de loin à un mini-programme. vous avez programmé une fonction bash qui lance un encodage mplayer avec des paramètres passés en ligne de commande ? Bingo ! Vous avez un petit script qui trie les photos de votre appareil numérique pour les ranger dans des dossiers correspondants aux dates des photos ? Jackpot ! Etc... Ce sont souvent des .sh ou des .pl. Parfois c'est simplement quelques lignes dans un .bashrc ou un .profile. Mais dans tous les cas : si ça vous est utile, ça le sera certainement à d'autres ! Et, surtout, n'oubliez pas de dire pourquoi vous avez utilisé tel langage plutôt que tel autre, parfois on se borne bêtement à ce que l'on connait bien, alors... Rien de mieux qu'un bon exemple pour remettre les choses en perspectives  :Wink:  !

Que la joute commence !

</trip>

----------

## Trevoke

Je me lance a l'eau le premier -- tout betement, ce qui nous est offert par defaut avec Gentoo : BASH script.

Exemples?

dans le .bashrc de root, un meilleur prompt :

```
PS1="\n\[\033[35m\]\$(/bin/date)\n\[\033[32m\]\w\n\[\033[1;31m\]\u@\h: \[\033[1;34m\]\$(/usr/bin/tty | /bin/sed -e 's:/dev/::'): \[\033[1;36m\]\$(/bin/ls -1 | /usr/bin/wc -l | /bin/sed 's: ::g') files \[\033[1;33m\]\$(/bin/ls -lah | /bin/grep -m 1 total | /bin/sed 's/total //')b\[\033[0m\] -> \[\033[0m\]"
```

des petits alias:

alias mypretend="emerge --newuse --update --deep --pretend world"

alias myemerge="emerge --newuse --update --deep world"

Et puis, un jour, je voudrais maitriser sed et awk  :Smile: 

----------

## billiob

Ca ne sert à rien, juste à faire beau au moment de se loguer : 

```

[0;01;31m                                           .

[0;01;31m     .vir.                                d$b

[0;01;31m  .d$$$$$$b.    .cd$$b.     .d$$b.   d$$$$$$$$$$$b  .d$$b.      .d$$b.

[0;01;31m  $$$$( )$$$b d$$$()$$$.   d$$$$$$$b Q$$$$$$$P$$$P.$$$$$$$b.  .$$$$$$$b.

[0;01;31m  Q$$$$$$$$$$B$$$$$$$$P"  d$$$PQ$$$$b.   $$$$.   .$$$P' `$$$ .$$$P' `$$$

[0;01;31m    "$$$$$$$P Q$$$$$$$b  d$$$P   Q$$$$b  $$$$b   $$$$b..d$$$ $$$$b..d$$$

[0;01;31m   d$$$$$$P"   "$$$$$$$$ Q$$$     Q$$$$  $$$$$   `Q$$$$$$$P  `Q$$$$$$$P

[0;01;31m  $$$$$$$P       `"""""   ""        ""   Q$$$P     "Q$$$P"     "Q$$$P"

[0;01;31m  `Q$$P"                                  """

[0;00;32m       +----------------------------------------> G N U \\ l  i  n  u  x      

[0;01;31m 

[0;01;34m This is \n.\O (\s \r) \d \t 

[0;01;34m         One 1667 MHz AMD Athlon(tm) XP 2000+ Processor,

[0;01;34m         512M RAM, 3301.37 Bogomips

[0;00m 

```

Si quelqu'un sait comment faire pour pouvoir changer la fin (One 1667 MHz AMD Athlon(tm) XP 2000+ Processor, 512M RAM, 3301.37 Bogomips) , en lisant /proc , je serais bien preneur.

Sinon, dans un autre genre, en BASH, pour lancer un jeu sur un autre serveur X (ici Enemy Territory) :

```
#!/bin/bash

cd /opt/enemy-territory

/usr/bin/X11/numlockx on &&

export DISPLAY=:1  &&

#pour avoir la molette de la sourie fonctionnelle :

xmodmap -display :1 -e "pointer = 1 2 3 6 7 4 5 8 9 10 11" &

xinit /usr/games/bin/et-tcetest $* -- :1

setxkbmap fr

```

Ce script marchait parfaitement sous xorg<=7.0, mais depuis la version modulaire, j'ai des problèmes avec Xlib, et il ne marche que lancé depuis un "tty".

----------

## gbetous

Perso, je suis un adepte des bon vieux scripts, a base d'une foultitude de programme (grep, cut, sed, awk...)

Pourtant je pense que rien ne vaut un bon perl ou pytho pour faire ce style de truc... mais je m'y suis jamais trop penché   :Crying or Very sad: 

----------

## anigel

 *billiob wrote:*   

> Si quelqu'un sait comment faire pour pouvoir changer la fin (One 1667 MHz AMD Athlon(tm) XP 2000+ Processor, 512M RAM, 3301.37 Bogomips) , en lisant /proc , je serais bien preneur.

 

```
cat /proc/cpuinfo | grep "model name" | cut -d':' -f 2
```

Ce genre de trucs ?

EDIT : cat /proc/cpuinfo : affiche le contenu du fichier /proc/cpuinfo

grep "model name" : n'affiche que les lignes qui contiennent la chaîne "model name"

cut -d':' -f 2 : affiche la 2ème colonne de texte seulement, en utilisant ':' comme séparateur de colonnes

----------

## billiob

 *anigel wrote:*   

> 
> 
> ```
> cat /proc/cpuinfo | grep "model name" | cut -d':' -f 2
> ```
> ...

 

Le seul problème, c'est que ces lignes ne sont pas interprétées comme ça; c'est pas du bash, je ne sais pas comment mettre de commande (il ne prend que  \O, \s ....)dedans  :Sad: . (J'essaierais quand même; Edit : ça ne marche pas  :Sad: , c'est interprété par agetty, donc à moins de refaire le /etc/issue à chaque fois, j'vois pas d'autre moyen. )

EDIT 2 : http://gentoo-wiki.com/TIP_Console_Prompt

----------

## anigel

Je n'avais pas fait attention au fait que tout ça était dans /etc/issue... J'avoue que je n'ai pas trop d'idées, car je présume que /etc/issue est lu, sans interprétation du code.. Par acquis de conscience, tu peux essayer de mettre ça entre back-quotes :

```
cat /proc/cpuinfo | grep "model name" | cut -d':' -f 2
```

Mais, sans grand espoir..

----------

## Trevoke

On pourrait aussi executer le code et le storer dans /etc/issue a chaque lancement de l'ordi dans /etc/init.d/ ... Non?

----------

## PabOu

anigel : et un chat mort !!! encore ;) j'entends par là un "cat | grep" alors que grep tout seul fonctionne très bien dans ce cas.

ma contribution. Pourquoi du perl ? parceque je me suis basé sur un script déjà en perl :

```
#!/usr/bin/perl -w

#

# wma2ogg.sh

#

# Transforme un .wma en .ogg grace à mplayer

# Nécessite de l'espace disque pour stocker le .wav temporaire

#

# la qualité du ogg de sortie est de 10 (paramètre -q 10)

#

use strict;

foreach my $file (@ARGV) {

next if ($file !~ /\.wma$/i);

my $base = $file; $base =~ s/\.wma$//i;

system "mplayer \"$file\" -ao pcm:file=\"$base.wav\"";

system "oggenc -q 10 \"$base.wav\" ";

unlink("$base.wav");

print "$base.wma converted to ogg.\n";

}
```

et un truc dans le même genre qui traine avec... ;)

```
#!/bin/bash

#############################################################

# wma2mp3 v0.12

# by Calum and Void Main

#

# e.g. wma2mp3 myfile.wma

# e.g. wma2mp3 myfile.wma myfile2.wma myfile3.wma

# e.g. wma2mp3 "my file.wma" "my file 2.wma" "my file 3.wma"

# e.g. wma2mp3 *.wma

# e.g. wma2mp3 /directory/containing/wma/files

# e.g. wma2mp3 .

#

# http://voidmain.is-a-geek.net/forums/viewtopic.php?t=407

#

# History:

# 16 May 2003 - v0.1 wma2mp3 script created

# 27 August 2005 - v0.11 -aofile had been deprecated, corrected

# 28 August 2005 - v0.12 Added "IFS=" -Void

#############################################################

# Turn off input field separation so filenames with spaces work

IFS=

#############################################################

# Move the conversion process into a function that can

# be called.

# The "&&" makes it so each step must be successful before

# the next step will be done.

#############################################################

function wma2mp3 () {

  if [ ! -f "$1" ]; then

     echo "File $1 not found!"

  else

     mplayer -ao pcm:file="${1%%.[Ww][Mm][Aa]}.wav" "$1" &&

     lame -h -b 192 "${1%%.[Ww][Mm][Aa]}.wav" "${1%%.[Ww][Mm][Aa]}.mp3" &&

     rm -f "${1%%.[Ww][Mm][Aa]}.wav" ||

     echo "There was a problem with the conversion process!"

  fi

}

#############################################################

# Not enough information to compute

#############################################################

if [ $# -lt 1 ]; then

   echo "Syntax: `basename $0` <wmaFilename(s)|wmaDirectory>"

   exit

fi

#############################################################

# Directory was passed so convert all wma files in directory

#############################################################

if [ $# -eq 1 -a -d "$1" ]; then

  for file in $1/*.[Ww][Mm][Aa]

  do

    wma2mp3 "$file"

  done

  exit

fi

#############################################################

# One or more wma files were passed, convert them

#############################################################

for file in $*

do

  wma2mp3 "$file"

done

exit

```

je possède également (je m'en sers assez souvent par curiosité) le script pour mesurer la fragmentation d'une partition (ReiserFS only ?) créé par TGL, que vous pouvez retrouver ici

----------

## Delvin

Petite question, pour gérer, ces "quick-hack" on peut les mettre dans le repertoire, par exemple /bin/scripts, avec les droits root, et rajouter ce chemin dans le path de son user

ma question : est-ce qu'un user pourra les executer tranquillement ?

----------

## TGL

Perso, comme certains ont déjà pu le remarquer vu que j'en poste de temps en temps ici, j'utilise beaucoup Bash (plus ses amis type sed et compagnie) pour les p'tits scripts faits à l'arrache. 

Grosso modo, ce que j'apprécie, c'est que ça se prête bien à une approche incrémentale. On peut faire des trucs déjà utiles et fonctionnels directement sur la ligne de commande, et c'est comme ça que ça commence en général, avec un simple "one-liner". Parfois ça en reste là (j'en fais juste un alias), et parfois ça grossit parceque je l'améliore petit à petit, et alors, pour l'éditer plus facilement, je le colle dans un fichier et je l'indente. Voilà, un script crade est né. 

Éventuellement, si il mérite d'être partagé, je le nettoie et complète encore un peu jusqu'à en faire un vrai programme présentable, avec des options et tout et tout. Et aboutir ainsi à des "vrais programmes" en Bash, c'est possible : prenez media-sound/abcde par exemple, il est super bien fini, non ? Pourtant, je m'avance un peu mais je doute que son auteur visait, quand il a écrit la première ligne du code, à faire le rippeur de CDs ultime. À mon avis, il est plutôt parti de quelques one-liners à usage personnel, et il a brodé autour pour en arriver là.

Le deuxième langage que j'utilise pour les p'tits scripts, c'est Python. Par rapport à Bash et ses amis, l'inconvénient est qu'on doit tout de suite faire un "vrai" script, que c'est souvent plus verbeux pour des choses très simples en Bash/grep/sed/etc.  Mais on gagne un langage plus puissant, avec notamment des structures de données difficiles à feindre en Bash. Donc selon les cas, on peut avoir :

 - des oneliners bash/sed/etc. qui demandent 30 lignes de code pour être faits en Python ;

 - des opérations simples de Python sur des structures complexes (des dictionnaires de listes de tuples, ou que sais-je), qui demande 10 lignes, 5 evals et 12 pipes pour être faits en Bash.

Et puis avec Python, on a accès à plein de modules super utiles pour éviter de réinventer la roue. Pour un gentooiste par exemple, un "import portage" vaut souvent bien des find, grep ou autre sed sur les fichiers de /usr/portage ou /var/db/pkg. 

Bref pour moi, Python ou Bash, ça dépend des besoins... Je choisis plutôt Python quand je sens que les choses ne pourront pas rester simples bien longtemps au niveau des structures de données, ou quand j'ai besoin d'un module spécifique. Le pire évidemment, c'est de se planter sur ce choix et de se rendre compte qu'on doit recoder en Python un truc commencé en Bash.

Quant à Perl, je peux pas en dire grand chose, j'ai jamais vraiment appris. Mais du peu que j'en connais et des utilisations que j'en vois de ci de là, je pense que c'est un bon candidat pour concurrencer à la fois les scripts Bash et les scripts Python :

 - l'accès aux fichiers texte et les opérations sur chaines de type grep/sed/etc. y sont beaucoup plus concises qu'en Python, donc il permet probablement de faire, sans exploser le nombre de lignes de code, ce que moi j'aurai tendance à faire en Bash. 

 - il se prête aussi assez très bien aux one-liners (comme Bash, et contrairement à Python).

 - les structures de données complexes ou les modules utilitaires valent ceux de Python, donc là non plus, pas de soucis.

Bref, ça pourrait bien être le langage qui réconcilie tous les usages du quick hack, mais bon, je crois que je ne le saurai jamais avec certitude, parceque sa syntaxe n'est vraiment pas à mon goût, et que j'ai pas envie de faire des efforts pour apprendre un truc dont je n'ai pas réellement besoin (ayant déjà le Bash et le Python dans ma besace).

Et enfin, pour l'anecdote, récemment j'ai vu un utilisé OCaml pour un machin que typiquement moi j'aurais fait en Python :

http://www.linux-france.org/lug/gulliver/ml-archives/mars-2006/msg00361.html

Et bah en fait, là ça s'y prêtait pas mal. Enfin je suis pas sûr que ça ait été le meilleurs choix possible non plus, mais disons que ça n'était pas complètement absurde : le programme est lisible (suffisament pour que j'envoie qlqs patchs à l'auteur alors que je n'avais pas fait d'OCaml depuis très longtemps), et pas trop long pour ce qu'il fait, donc bref, pourquoi pas...

----------

## DaiKo

Personnellement j'ai decouvert Python recement et j'adhere, c'est pas que je fasse souvent des scripts, mais quand cela m'arrive j'utilise python...

----------

## bibi.skuk

 *TGL wrote:*   

> 
> 
> Et puis avec Python, on a accès à plein de modules super utiles pour éviter de réinventer la roue. Pour un gentooiste par exemple, un "import portage" vaut souvent bien des find, grep ou autre sed sur les fichiers de /usr/portage ou /var/db/pkg. 
> 
> 

 

Tu aurait une adresse ou un moyen d'avoir un peu de doc a propos des fonctions de portage ??

pour ma part, j'utilise perl et bash... mais de plus en plus, je me dirige vers python, qui a l'avantage de pouvoir etre relu... par rapport au perl... 

La plus part des scripts que j'ai fait tenait du one-liner, de temps en temps, je les garde pour y revenir plus tard, mais pas possible de se relire... (je haie le perl a cause de ca... je l'aime aussi pour la même raison, mais chut ;p)

----------

## TGL

 *bibi.skuk wrote:*   

> Tu aurait une adresse ou un moyen d'avoir un peu de doc a propos des fonctions de portage ??

  

```
% $EDITOR /usr/lib/portage/pym/*.py
```

  :Laughing: 

Sérieusement, niveau documentation c'est pas trop ça, et tu te retrouves souvent à aller voir les sources pour trouver la fonction que tu cherches (évidemment, un éditeur qui y comprend qlqchose au Python, genre Vim ou Cream avec CTags, ou bien les GUI qui viennent avec wxpython, ça aide). Et puis les autres scripts existants, genre ceux de gentoolkit, peuvent aussi être de bon conseil.

Y'a ceci dit qlqs tentatives de documentation, mais rien qui soit complet ou bien maintenu à jour :

http://portage.wiki.gentooexperimental.org/

http://dev.gentoo.org/~kutsuya/

----------

## kwenspc

[mavie]

Moi c'est le python, surtout, et le bash

[/mavie]

Je trouve le python trés élégant et pour peu qu'on ai besoin de quelque chose de conséquent et de maintenable c'est un langage qui s'y prete bien.

Le bash je l'utilise surtout sur des scripts système comme pour parser rapido la sortie de la commande ps, ou autre.

Pour un problème vous avez une tonnes de solutions toutes aussi simples les unes des autres (bon ok vous pouvez faire trés compliqué aussi mais avec le bash c'est pas gagné)

Il va a l'essentiel quoi. En une ligne on peut faire un truc super compliqué et avoir un résultat époustouflant. (quelqu'un l'a déjà noté plus haut je crois)

----------

## scout

Bon alors moi j'utilise du bash, donc je ne vais pas en rajouter là dessus, et sinon du:

RUBY

Ruby est excellent, et contrairement à python on peux faire des one-liners, puisque ruby ne considère pas l'indentation.

irb est pour cela très pratique: on fait son one-liner progressivement et interactivement.

Le mécanisme des itérateur est excellent et les Array et compagnie ont 10000 méthodes utiles.

pour preuve sireyessire me parlais de code de césar l'autre jour.

Rappel: chaque lettre est changée pour une autre lettre "offset" plus loins dans l'alphabet.

par exemple si offset=2, alors a deviens c, b deviens d, ... x=>z, y => a, z=>b

Voilà ce que ça donne très rapidement:

```
irb(main):001:0> str='coucou voici le truc a crypter'

=> "coucou voici le truc a crypter"

irb(main):005:0> offset=5; res=''; str.each_byte { |b| if b.chr==' ' then res << ' '; else res << ((b-?a)+offset)%26 + ?a; end }; res

=> "htzhtz atnhn qj ywzh f hwduyjw"

irb(main):006:0> offset=-5; str=res; res''; str.each_byte { |b| if b.chr==' ' then res << ' '; else res << ((b-?a)+offset)%26 + ?a; end }; res

=> "coucou voici le truc a crypter"
```

quelques explications:

l'itérateur each_byte itère sur la chaine et b deviens le byte du caractère considéré

?a c'est 97: le code ascii de a; donc quand je fais b-?a c'est le numéro de la lettre en partant de zéro pour la lettre a

on rajoute l'offset et on fait un modulo 26

on rajoute le code ascii de a avant de concaténer à la chaine résultat res avec l'opérateur <<

à la fin on affiche la chaine res

pour la décryption, on initialise str avec la valeur cryptée, et l'offset à -5.

Tout ça pour dire que j'aime bien faire des one liners en ruby; et je me sers très souvent de irb comme calculette

Autre exercice de style; la transformée de Burrows-Wheeler, que j'ai découvert en faisant un tour sur la page de bzip2 de wikipedia.

l'algorithme est expliqué ici: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform

Je choisis le caractère 'Z' comme EOF (cf wikipedia) et je ne rentrerais que des chaines qui ne contiennent pas ce caractère

en ruby: (top chrono départ du codage à 20h05; fin à 20h20 sans les commentaires)

```
#!/usr/bin/ruby -w

def rotate(str)

    return str[-1].chr+str[0..-2]

end

def codage(str)

    str=str+'Z' # str est modifié localement à la fonction

    table=[]

    1.upto(str.length) do

        table << str.scan(/./) # str.scan(/./) transforme la chaine str en tableau de caracteres isolés

        str=rotate(str)

    end

    return table.sort.transpose[-1].join

end

def decodage(str)

    str_caracteres_un_a_uns=str.scan(/./)

    table=[str_caracteres_un_a_uns].transpose

    1.upto(str.length-1) do # on fait la boucle de l'algo

        table=[str_caracteres_un_a_uns] + table.sort.transpose

        table=table.transpose

    end

    table.each do |str| # on cherche la ligne qui se termine par 'Z'

        if str[-1]=='Z'

            return str[0..-2].join()

        end

    end

end
```

voilà.

Ma méthode de dével: dans du vim, et périodiquement je fais:

w | irb -r rotate.rb

ce qui permet d'écrire les modifs du fichier, et de charger les fonctions dans irb pour pouvoir tester. (mon fichier s'appellait rotate.rb)

j'ai débuggé avec la fonction 'p' qui m'affiche la table de manière verbeuse.

exemple du irb -r rotate.rb:

```
irb(main):001:0> codage('hello world of gentooists under gentoo on gentoo computers')

=> "onrfdosos lnhgggdto   Zorelooueeeool oc tttwmeoetriunnns p "

irb(main):002:0> decodage(codage('hello world of gentooists under gentoo on gentoo computers'))

=> "hello world of gentooists under gentoo on gentoo computers"
```

j'ai écrit plein de fois le mot 'gentoo' pour qu'on voie apparaitre l'intérêt de l'algo, à savoir transformer des répétitions de mots en répétitions de caractères consécutifs.

Voilà, c'était rigolo. J'ai pas essayé de tourner le truc en un machin incompréhensible au non rubyistes, et c'est du code que j'arriverais à relire dans 6 mois, contrairement à mes essais de perl. là je peux relire mes scripts ruby de décalage de sous titres et les comprendre parfaitement alors que ça fait un bail que je les ai écris. je sais qu'on peux écrire du perl propre, mais il y a juste que j'ai arrété d'apprendre le perl quand Sleeper m'a fait découvrir ruby (merci Sleeper  :Mr. Green: )

----------

## geekounet

J'ai justement commencé à apprendre le ruby cet aprem, comme ça sur un coup de tête (non c'était pas trop douloureux  :Laughing: )

Et merci scout, tu en rajoute à ma motivation, je suis encore plus convaincu que c'est le langage qu'il me faut  :Smile: 

Sinon en ce qui me concerne, je ne scripte pas beaucoup, mais quand il faut c'est toujours en bash jusque là  :Smile: 

----------

## BuBuaBu

Pour ma part, c'est php + bash.

Php peu paretre inatendu, mais il permet de faire rapidement une interface graphique pour des tache simple.

Par exemple remplir une crontab pour lancé mencoder.

Bien entendu mon utilisateur ne voit rien, et il se croi sur une magnetoscope par exemple.

Ok, c'est un peu lourd, il faut un serveur web et un naviguateur.

----------

## PabOu

ah non, tu peux utiliser du php en ligne de commande (cli).

tu dois compiler php avec le useflag cli.

plus d'infos ici.

Je pense que le php étant très facile (et d'une syntaxe proche du C parceque basé sur le C), il peut convenir à beaucoup de gens. Et puis, beaucoup de gens connaissent (un peu ou beaucoup) le php.

----------

## mornik

Perso j'utilise presque exclusivement  bash. Et j'ai pas grand chose à proposer en script car je suis en ce moment entrain de me faire un script pour graver mes cd/dvd (data, iso, audio etc), car j'ai rien trouvé de bien convaincant dans ce domaine sauf k3b, mais comme ni qt ni kde sont installés sur ma machine...

----------

## loopx

 *billiob wrote:*   

> Ca ne sert à rien, juste à faire beau au moment de se loguer : 
> 
> ```
> 
> [0;01;31m                                           .
> ...

 

Heu, il y aurait moyen d'avoir plus d'info sur ce truc la, parce que ca m'intéresse... C'est généré automatiquement tout ca ? J'ai cherché dans google, mais j'ai pas trouvé de bon site, j'ai rien dans ce fichier /etc/issue   :Crying or Very sad:   a part la ligne que tu veux enlever...

----------

## PabOu

 *billiob wrote:*   

> EDIT 2 : http://gentoo-wiki.com/TIP_Console_Prompt

 

loopx, je crois que c'est ca que tu recherches :)

----------

## loopx

Ouips, c'est bien ca que je cherche  :Smile: 

----------

## Pog

hello hello,

ca ma donné une idée  :Razz: 

enfin que j'ai piqué sur le wiki > ma source d'inspiration

dans mon ~/.bashrc

```
cowsay -d `fortune -s bofh-excuses`
```

et op je me marre quand je me log sur le serveur de supervision   :Embarassed: 

----------

## xaviermiller

 *loopx wrote:*   

>  *billiob wrote:*   Ca ne sert à rien, juste à faire beau au moment de se loguer : 
> 
> ```
> 
> [0;01;31m                                           .
> ...

 

et un bête

```
man issue
```

ou

```
man /etc/issue
```

  :Question: 

----------

## killerwhile

Allez hop une contribution : un petit script minute maid sans prétention et pas optimisé qui pourrait être utilisé pour gagner une voiture ou comme tout autre traffic booster...

En gros il télécharge une URL à une certaine fréquence, et peut utiliser un nombre configurable de proxy...

Et je décline toute responsabilité en cas d'utilisation abusive (et si ça sortirait du cadre éthique du forum, n'hésitez pas à supprimer le post)

```
#!/bin/bash

# 

# Get remote web page at an average given frequency

# 

#  written by Ki11erwhi1e

# 

# Usage : ./wget_url.sh http://www.target.com/

# 

# The script is designed to be called by a crontab each minute

# This makes 60 calls per hour, 1440 calls per day

#

#

# For a call in average every hours, set PERIOD=547

# For a call every day, set PERIOD=23

#

PERIOD=547

# 

# The page which must be called

# It can also be passed in argument of the script

# 

URL="http://www.target.com"

# 

# User agent which get the page

# 

USER_AGENT="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"

# 

# Referer of the page (to simulate a click to the page

# 

REFERER="http://www.google.ch/search?q=target"

# 

# Number of proxy to use. 

# 0 means don't use a proxy

# n > 0 means use max n proxies (and perform n call)

#

USEMAXPROXY=5

WGET=`which wget`

getUrl() {

   $WGET --user-agent="$USER_AGENT" --page-requisites --no-verbose --delete-after \

   --convert-links --referer="$REFERER" \

   --tries=1 --timeout=5 --proxy \

   "$1"

}

if [ "$1" != "" ]

then

   URL=$1

fi

if [ $RANDOM -lt $PERIOD ] 

then

   if [ $USEMAXPROXY -gt 0 ]

   then

      PROXYRAWFILE=/tmp/proxyrawfile.txt

      PROXYLIST=/tmp/proxylist.txt

      PROXYLIST2=/tmp/proxylist2.txt

      wget --timestamping --no-verbose -O $PROXYRAWFILE http://www.publicproxyservers.com/page1.html;

      sed "s/<[^>]*>//g" < $PROXYRAWFILE | egrep "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$|^[0-9]{2,4}$" > $PROXYLIST

      for l in `cat $PROXYLIST`; do if [ "$p" == "" ]; then p=$l; else echo $p:$l >> $PROXYLIST2; p=""; fi; done

   fi

   

   #VALUE=$RANDOM

   #echo $VALUE

   

   if [ $USEMAXPROXY -gt 0 ]

   then

      for p in `cat $PROXYLIST2 | head -n $USEMAXPROXY`

      do

         echo "# "

         echo "# Use proxy $p"

         echo "# "

         http_proxy=$p getUrl $URL

      done

      

      rm -f $PROXYRAWFILE

      rm -f $PROXYLIST

      rm -f $PROXYLIST2

      

   else

      getUrl $URL

   fi

fi
```

----------

## Oupsman

Moi c'est :

Korn SHell au taf (je suis administrateur AIX)

Bourne Again SHell chez moi. Je suis en train de réécrire mon script de sauvegarde, pour en faire un truc un peu plus facilement paramétrable.

Perl dans certains cas (d'ailleurs, mon script de sauvegarde, je suis en train de me tâter pour le réécrire en Perl)

----------

## Sleeper

Pour moi, c'etait Perl, mais depuis 2 ou 3 ans c'est Ruby.

 *Oupsman wrote:*   

> 
> 
> Bourne Again SHell chez moi. Je suis en train de réécrire mon script de sauvegarde, pour en faire un truc un peu plus facilement paramétrable.
> 
> Perl dans certains cas (d'ailleurs, mon script de sauvegarde, je suis en train de me tâter pour le réécrire en Perl)

 

Arf ... le classique ... j'ai commence y'a quelque temps a en re-ecrire un, mais j'ai pas le temps (ni l'envie  :Wink:  de le terminer. Le but etait de faire un truc propre: le fichier de config des backups ressemble a qq chose comme:

```

Backup::Full.new('configs') { 

  frequency :daily

  located_in "/users/fros/essais/ruby/bck/"  # Where tarballs will be saved

  includes Dir['/users/fros/essais/ruby/*.yaml'] # What we do want to save

}

Backup::Incremental.new( 'repository' ) do

  frequency :monthly

  located_in "/foo/bar"

  use_working_dir toto   ## Will issue a <cd toto> before anything (tarball and so on)

  includes Dir['**/*,v']

end

```

----------

## GuillaumeB

 *scout wrote:*   

> Ruby est excellent, et contrairement à python on peux faire des one-liners, puisque ruby ne considère pas l'indentation.
> 
> pour preuve sireyessire me parlais de code de césar l'autre jour.
> 
> ```
> ...

 

Rien compris au code  :Smile:  ?a << >> ! ² ~ !! ^ (des fans de la lib aa ici ?) Disont qu'il faut de l'experience pour lire le Ruby.

Et contrairement aux idees reçu, python peut faire des onlines :

```

>>> subject = 'coucou voici le truc a crypter'

>>> offset=5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])

'htzhtz atnhn qj ywzh f hwduyjw'

>>> subject=_

>>> offset=-5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])

'coucou voici le truc a crypter'

```

J'admet, c'est immonde, Python 2.5 ameliorera un peut cela avec l'ajout des structure conditionelle, cela donnera :

```

>>> subject = 'coucou voici le truc a crypter'

>>> offset=5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97) if i == ' ' else ' ') for i in subject])

'htzhtz atnhn qj ywzh f hwduyjw'

```

Bon, je readmet, c'est ultra immonde, mais python n'est pas fait pour ça (j'avoue que des fois Ruby me tente pour les trucs funs faisables avec ;o)

Pour répondre à la question originel: Scripting bash onliners rapide quand je sais faire, après je saute dans le Python si la réflexion en bash me prend plus de 30 secondes.

 *Quote:*   

> 
> 
> Tout ça pour dire que j'aime bien faire des one liners en ruby; et je me sers très souvent de irb comme calculette
> 
> 

 

Pareil ici en ce qui concerne le shell python  :Smile: 

 *Quote:*   

> 
> 
> Autre exercice de style; la transformée de Burrows-Wheeler, que j'ai découvert en faisant un tour sur la page de bzip2 de wikipedia.
> 
> en ruby: (top chrono départ du codage à 20h05; fin à 20h20 sans les commentaires)
> ...

 

En python, top chrono depart 14:58 fin 15:11

```
# -*- coding: iso-8859-1

# module permetant de crée des listes tournantes

from collections import deque

EOF = 'Z'

def BWT(s):

   assert EOF not in s

   

   # On convertit notre chaine en liste d'éléments tournants

   s = deque(s + EOF)

   liste = []

   # Iterations sur la longueur de la chaine

   for i in range(len(s)):

      

      # on ajoute à la liste la chaine et on tourne

      liste.append(''.join(s))

      s.rotate()

   

   # Sort + retour des derniers elements de la liste

   liste.sort()

   return ''.join([i[-1] for i in liste])

def unBWT(s):

   # création d'une liste vide de longeur de s

   liste = [''] * len(s)

   

   for i in range(len(s)):

      # On ajoute les valeurs et on classe

      liste = [s[i] + liste[i] for i in range(len(s))]

      liste.sort()

   # Un peut crade ici :)

   # On renvoie le premier element d'une

   # liste qui contient tous les elements

   # de la liste précedent qui finissent par Z

   # On oublie pas de virer le EOF

   return [i for i in liste if i.endswith('Z')][0].strip(EOF)

if __name__ == '__main__':

   subject = 'hello world of gentooists under gentoo on gentoo computers'

   trans = BWT(subject)

   assert unBWT(trans) == subject

```

Bref, c'est kiff kiff  :Smile: 

Voilà, c'était rigolo aussi, je crois que les deux langages se valent (on va dire que j'ai mis deux minutes de moins parce que je suis doué  :Smile: 

----------

## ultrabug

Salut

Moi exactement pareil que TGL, Bash ou Python selon la complexité finale de la chose  :Smile: 

----------

## Sleeper

 *GuillaumeB wrote:*   

> 
> 
> Rien compris au code  ?a << >> ! ² ~ !! ^ (des fans de la lib aa ici ?) Disont qu'il faut de l'experience pour lire le Ruby.
> 
> Et contrairement aux idees reçu, python peut faire des onlines :
> ...

 

T'es pas un peu de mauvaise foi ? C'est sur que 97 c'est bcp plus parlant que ?a  :Wink: 

Ce dont voulait sans doute parler Scout c'est de vrai one-liner ... Par exemple sur une des becanes que j'utilise au boulot, je n'ai pas wget ... par contre y'a ruby ... donc je fait un one-liner que j'appellerai le wget du pauvre:

```

ruby -r'open-uri' -e'open("http://linuxfr.org"){ |f| puts f.read }' > index.html

```

et honnetement, le join sur un for .. in ... c'est pas mega clair .... J'aime bien mais c'est pas forcement clair. Tant quà faire autant utiliser inject:

```
'coucou voici le truc a crypter'.split('').inject("") {|res,c| res << (c == " " ? " " : ((c[0]-?a)+5)%26+?a)}
```

Note au passage qu'on pourrait faire plus simple, en utilisant une translation:

```

irb> src = ('a'..'z').to_a.join

=> "abcdefghijklmnopqrstuvwxyz"

irb> dest = src.slice(5..-1) + src.slice(0,5)

=> "fghijklmnopqrstuvwxyzabcde"

irb> "coucou voici le truc a crypter".tr(src,dest)

=> "htzhtz atnhn qj ywzh f hwduyjw"

```

Ce qui est interessant avec Ruby (et je pense que Python doit aussi savoir le faire) c'est de pouvoir ré-ouvrir toutes les classes (même celles de base)... Par exemple, si on veut ajouter notre methode "codage" à la classe String:

```

irb(main):008:0> class String

irb(main):009:1> def codage( offset = 5 )

irb(main):010:2> src = ('a'..'z').to_a.join

irb(main):011:2> dest = src.slice(offset..-1) + src.slice(0,offset)

irb(main):012:2> tr(src,dest)

irb(main):013:2> end

irb(main):014:1> end

=> nil

irb(main):015:0> "coucou voici le truc a crypter".codage

=> "htzhtz atnhn qj ywzh f hwduyjw"

irb(main):016:0> "coucou voici le truc a crypter".codage(1)

=> "dpvdpv wpjdj mf usvd b dszqufs"

```

Toute chaine a alors accès à la méthode codage ..  :Smile: 

----------

## GuillaumeB

[quote="Sleeper"]

T'es pas un peu de mauvaise foi ? C'est sur que 97 c'est bcp plus parlant que ?a  :Wink: 

[quote]

Un peu  :Smile:  J'aurais dû dire ord('a').

 *Quote:*   

> 
> 
> Ce dont voulait sans doute parler Scout c'est de vrai one-liner ... Par exemple sur une des bécanes que j'utilise au boulot, je n'ai pas wget ... par contre y'a ruby ... donc je fait un one-liner que j'appellerai le wget du pauvre:
> 
> 

 

Ils vous mettent Ruby mais pas wget... C'est qui ces admins ?

 *Quote:*   

> 
> 
> Note au passage qu'on pourrait faire plus simple, en utilisant une translation:
> 
> ```
> ...

 

estétique... On peut aussi le faire en Python, mais cela prendre quelques lignes de plus :

```

>>> import string

>>> offset = 5

>>> tr = string.maketrans(string.ascii_lowercase,string.ascii_lowercase[offset:] + string.ascii_lowercase[:offset])

>>> out = "coucou c'est nous".translate(tr)

>>> offset = -5

>>> tr = string.maketrans(string.ascii_lowercase,string.ascii_lowercase[offset:] + string.ascii_lowercase[:offset])

>>> out.translate(tr)

"coucou c'est nous"

```

Ce que j'aime beaucoup en Ruby c'est les ensembles sur les lettres (a..z) ainsi que le nombre impressionnant de méthode pour chaque classe.

 *Quote:*   

> Ce qui est intéressant avec Ruby (et je pense que Python doit aussi savoir le faire) c'est de pouvoir ré-ouvrir toutes les classes (même celles de base)... Par exemple, si on veut ajouter notre méthode "codage" à la classe String:
> 
> ```
> 
> irb(main):008:0> class String
> ...

 

Alors oui et non. On peut et on ne peut pas :

```

>>> from datetime import datetime

>>> def whatthedaytoday(self):

...     return "Aujourd'hui on est le %d" % self.day

...

>>> datetime.whatthedaytoday = whatthedaytoday

Traceback (most recent call last):

  File "<stdin>", line 1, in ?

TypeError: can't set attributes of built-in/extension type 'datetime.datetime'

>>> from decimal import Decimal

>>> def to_int(self):

...     return int(self)

...

>>> Decimal.to_int = to_int

>>> i = Decimal('50.25')

>>> i

Decimal("50.25")

>>> i.to_int()

50

```

C'est un de mes regrets, les modules builtins (généralement ceux fait en C et non pas en Python) ne permettent pas ce genre de mécanisme.

Maitenant les avis divergent à ce sujet. Certains disent qu'il ne vaut mieux pas modifier le langage, c'est plus simple à relire. Exemple, en Ruby quelqu'un va lire machaine.codage(), il va se demander si codage est un ajout de ta part ou alors fournit avec la librairie standard. En Python on préfère sacrifier l'estétique au profit de la vitesse de relecture. Un amis disais : « Python c'est très bien pour monter un projet, mais si tu as envie de te faire plaisir, fait du Ruby. » Un jour je m'y mettrais sérieusement. Un autre exemple qui fait la force et la faiblesse de Ruby, il fait tout à la fois avec des effets de bords étonnants:

```

irb(main):007:0> a = [1,5,2]

=> [1, 5, 2]

irb(main):008:0> b = a.sort!()

=> [1, 2, 5]

irb(main):009:0> b

=> [1, 2, 5]

irb(main):010:0> a

=> [1, 2, 5]

>>> a = [1,5,2]

>>> b = a.sort()

>>> a

[1, 2, 5]

>>> print b

None

```

N'empêche tout cela me donne envie de me repencher sur Ruby... Aller, je finis mon année et je m'en occupe.

----------

## boozo

'alute

je ne pite pas tout au débat mais c'est 'achement intéressant votre échange là   :Wink: 

on sent déjà se profiler un DOW Python vs Ruby   :Laughing:  comment ?! on y est déjà ?

gardez-en sous le pied qd m^   :Wink: 

----------

## geekounet

Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces  :Wink: 

----------

## GuillaumeB

 *pierreg wrote:*   

> Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces 

 

Un avis qui essaye d'être le plus objectif possible (ce qui n'est pas possible vu que je connais très bien python et très mal Ruby).

L'un suit une philosophie très particulière (ouvre une console python et tape "import this") qui des fois est vexante mais est agréable quand l'on doit bosser sur un gros projet (Python est explicite, indentation importante, clareté...)

Maitenant Ruby est plus "fun" et permet de faire des choses des fois en moins de ligne avec des méthodes plus artistiques.

C'est sur cela qu'il faut faire son choix car en matière de possibilitées et librairies externe, c'est kif kif, avec des fois certains avantages pour l'un ou l'autre.

----------

## kwenspc

Intéressant ce petit débat.

Enfin cela me conforte dans l'idée que peu de langages peuvent se permettre, à l'instar de python donc, de pouvoir être massivement utilisé dans le monde professionel et ce justement parce que python oblige à être clair un minimum, qu'il est trés facile de faire des choses propres etc...

Le côté "fun" est à des années lumières des préoccupation de ce monde là   :Wink: 

( sauf si vous êtes votre propre patron  :Mr. Green:  )

----------

## Sleeper

 *pierreg wrote:*   

> Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces 

 

Disons que Python est un très bon language. Mais je n'aime pas Python: c'est de l'ordre des gouts et des couleurs ...

J'ai essayé d'apprendre Python fin 98, mais le coup des indentations ne me plaisait pas ... J'ai voulu ré-éssayer y'a 4 ans ..mais la c'est le coup du self comme premier argument de chaque fonction (avec une explication boiseuse), et le coup d"il n'y a qu'une seule bonne façon de le faire" qui ne m'ont vraiment pas plu .... mais je pense quand même que c'est un bon language ... même si Ruby est meilleur (je plaisante, on, pas les dents !!)

----------

## Sleeper

 *kwenspc wrote:*   

> Intéressant ce petit débat.
> 
> Enfin cela me conforte dans l'idée que peu de langages peuvent se permettre, à l'instar de python donc, de pouvoir être massivement utilisé dans le monde professionel et ce justement parce que python oblige à être clair un minimum, qu'il est trés facile de faire des choses propres etc...
> 
> Le côté "fun" est à des années lumières des préoccupation de ce monde là  
> ...

 

Pas d'accord ... Quelque soit le language tu peux écrire des trucs pourris, et illisibles ... Disons que Ruby est moins bavard que Python, ce qui ne veut pas dire moins lisible ....

----------

## Sleeper

 *GuillaumeB wrote:*   

> Un autre exemple qui fait la force et la faiblesse de Ruby, il fait tout à la fois avec des effets de bords étonnants:
> 
> ```
> 
> irb(main):007:0> a = [1,5,2]
> ...

 

Euh je vois pas trop ou est l'effet de bord là ... Certaines méthodes existent en 2 versions: sans effect de bord (exemple: sort) et avec effet de bord (exemple: sort!) :

```

irb(main):001:0> a = [1,5,2] 

=> [1, 5, 2]

irb(main):002:0> b = a.sort

=> [1, 2, 5]

irb(main):003:0> b

=> [1, 2, 5]

irb(main):004:0> a

=> [1, 5, 2]

irb(main):005:0> a.sort!

=> [1, 2, 5]

irb(main):006:0> a

=> [1, 2, 5]

```

----------

## GuillaumeB

 *Sleeper wrote:*   

> 
> 
> Euh je vois pas trop ou est l'effet de bord là ... Certaines méthodes existent en 2 versions: sans effect de bord (exemple: sort) et avec effet de bord (exemple: sort!) :
> 
> 

 

Ce qui me choque c'est que cela fasse deux choses, trier la liste et renvoyer une/la liste (la même ou un autre...) J'en sait trop rien.

----------

## Sleeper

 *GuillaumeB wrote:*   

> 
> 
> Ce qui me choque c'est que cela fasse deux choses, trier la liste et renvoyer une/la liste (la même ou un autre...) J'en sait trop rien.

 

Ben justement ... Ca te renvoie un tableau ... qui te permet d'enchainer les méthodes:

```

[5,2,1].sort.compact.join(", ")

```

sort renvoie un tablea, on peut donc lui appliquer compact, qui renvoie un tableau à qui on peut appliquer join ... etc ...

----------

## TGL

 *Sleeper wrote:*   

> sort renvoie un tablea, on peut donc lui appliquer compact

 

Heu, c'est plutôt avant le sort() qu'on appellera compact(), puisque les éléments nil n'ont pas de méthode de comparaison et ne sont donc ordonnables avec rien. Enfin bon, on s'en fout, c'était juste un exemple comme ça je suppose.

Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça : 

```
a.sort!

b=a.join(",")
```

 que ça : 

```
b=a.sort!.join(",")
```

 Ceci parceque le second peut facilement être relu de travers (on peut ne pas se rendre compte que a est modifié). 

Mais d'un autre côté, c'est très pratique que ces méthodes machin!  renvoient une ref à l'objet qu'elles ont affecté, parceque ça permet de les enchainer (et c'est peut être ça que tu voulais dire Sleeper ?). Genre dans cet exemple, ça fait sens, et c'est parfaitement lisible, de profiter de la ref renvoyée par compact!() : 

```
a = [1,nil,5,2,nil]

a.compact!.sort!
```

C'est aussi, de manière générale, cohérent avec les autres affectations : après tout, un simple a=qlqchose a lui aussi une valeur de retour... (bien pratique elle aussi, ne serait-ce que pour les "a = b = qqch")

Bref, c'est un truc à utiliser à bon essien, et puis voilà. Un peu comme les machin++ ou ++truc du C (ou autre), qui isolément sont bien pratiques et lisibles, genre pour boucler sur des accès à tableau[++i], mais qui, multipliés au sein d'une expression arithmétique (genre d = ++a*(b + c++);), rendent le code pénible à déchiffrer (comparé à un ++a; d=a*(b+c); ++c;).

Après, évidemment, il y a une part de subjectivité là dedans. Genre perso, entre ces deux codes, j'hésite : 

```
a.compact!

print a.join(",") if a
```

```
print a.join(",") if a.compact!
```

Dans le second, la modification de a est un peu cachée, mais pas trop quand même, donc bon, moi je relis aussi bien les deux. Mais certains préfèreront sûrement l'une ou l'autre version.

Et pour répondre à la question «(la même ou un autre...) J'en sait trop rien.» de GuillaumeB : c'est bien de la même liste qu'il s'agit. Ce sont, de manière générale, des méthodes de modification des objets, et elles ne font pas de copie. Logique d'ailleurs, puisque sinon un a.compact!.sort! ferait le compact! sur a mais le sort! sur une copie, ce qui serait vachement moins utile.

----------

## GuillaumeB

 *TGL wrote:*   

> 
> 
> Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça : 
> 
> ```
> ...

 

Voila, c'est ça mon problème.

 *Quote:*   

> 
> 
> Mais d'un autre côté, c'est très pratique que ces méthodes machin!  renvoient une ref à l'objet qu'elles ont affecté, parceque ça permet de les enchainer (et c'est peut être ça que tu voulais dire Sleeper ?). Genre dans cet exemple, ça fait sens, et c'est parfaitement lisible, de profiter de la ref renvoyée par compact!() : 
> 
> ```
> ...

 

J'avais pas vu cela comme ça, en effet.

 *Quote:*   

> 
> 
> Et pour répondre à la question «(la même ou un autre...) J'en sait trop rien.» de GuillaumeB : c'est bien de la même liste qu'il s'agit. Ce sont, de manière générale, des méthodes de modification des objets, et elles ne font pas de copie. Logique d'ailleurs, puisque sinon un a.compact!.sort! ferait le compact! sur a mais le sort! sur une copie, ce qui serait vachement moins utile.

 

Remarque que 

```
a.sort()
```

 fait une copie lui ;o) Bon, je suis de mauvaise foi, mais je comprend mieux le mécanisme. C'est puissant, mais cela peu être troublant.

----------

## Sleeper

 *TGL wrote:*   

> 
> 
> Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça : 
> 
> ```
> ...

 

C'est pour celà que justement, on n'enchaine pas souvent les méthodes qui modifient l'objet de "départ" ...

L'avantage (combiné au fait que l'on puisse ré-ouvrir les classes) c'est de pouvoir écrire des choses du genre:

```

>> 10.minutes.ago

=> Sat Apr 29 13:39:17 CEST 2006

```

quand on a les helpers fournis avec Rails ... C'est quand même plus parlant que ago(minutes(10)) ...

 *Quote:*   

> 
> 
> Bref, c'est un truc à utiliser à bon essien, et puis voilà. Un peu comme les machin++ ou ++truc du C (ou autre), qui isolément sont bien pratiques et lisibles, genre pour boucler sur des accès à tableau[++i], mais qui, multipliés au sein d'une expression arithmétique (genre d = ++a*(b + c++);), rendent le code pénible à déchiffrer (comparé à un ++a; d=a*(b+c); ++c;).
> 
> 

 

Oui et non ... ce n'est pas seulement une facilité d'écriture mais plutôt IMHO de lecture ainsi que de "localité de code" (on groupe ce qui va fonctionnellement ou logiquement ensemble)

 *Quote:*   

> 
> 
> Après, évidemment, il y a une part de subjectivité là dedans. Genre perso, entre ces deux codes, j'hésite : 
> 
> ```
> ...

 

Hummm ... je préfère 

```

puts a.join(",") unless a.compact!.nil?

```

ou alors 

```

puts (a.compact! || a).join(", ")

```

qui affichera a dans tous les cas ...

----------

## Sleeper

 *GuillaumeB wrote:*   

> 
> 
> Remarque que 
> 
> ```
> ...

 

Oui, c'est justement la différence entre sort() et sort!()  :Wink: 

----------

## TGL

 *GuillaumeB wrote:*   

> Remarque que 
> 
> ```
> a.sort()
> ```
> ...

 

Remarque que en Python y'a deux méthodes aussi, avec la même distinction : machin.sort() pour modifier trier la liste machin, et sorted(machin) pour en obtenir une copie triée. La seule différence, c'est que machin.sort() ne renvoie rien. Ça correspond bien à la philosophie Python (une seule bonne façon de faire qqch : ici, une décomposition en plusieurs lignes si on veut filtrer puis trier puis etc.), mais je comprends tout à fait que ça ne plaise pas à tout le monde (et perso ça me gonfle aussi parfois).

 *Quote:*   

> C'est puissant, mais cela peu être troublant.

 

Oui, c'est Ruby quoi... Globalement, je dirais que c'est un langage qui s'improvise moins que le Python. Il y a plus de subtilités, il est plus difficile de comprendre du code quand on ne connait pas le langage, et il faut en passer par un peu de lecture de la doc. Mais d'un autre côté, le gros point fort de Ruby c'est à mon sens sa cohérence : le langage a vraiment été penser avec des concepts clairs et les plus largement applicables possibles, donc quand tu piges un truc (comme ici le coup des method vs. method!), bah il est valable partout, et t'as vraiment aucune chance d'avoir des surprises avec par la suite. C'est à mon avis beaucoup moins vrai en Python, où tout le monde sait par exemple, pour l'avoir vu utilisé 36 fois, que len est un builtin, et qu'il n'y a pas de méthode liste.len(), mais où personne ne pourrait vraiment expliquer pourquoi.

Bon, bref, je peux l'avouer, point de vu langage je préfère Ruby à Python. Ceci dit, c'est Python que j'utilise le plus, de loin, parceque je le connais depuis plus longtemps et donc mieux, et parceque lui seul autorise les "import portage". En gros, Python et moi on est un vieux couple, on se côtoie au quotidien, alors que Ruby c'est la petite jeunette que je vais voir un weekend de temps en temps...

----------

## TGL

 *Sleeper wrote:*   

> C'est pour celà que justement, on n'enchaine pas souvent les méthodes qui modifient l'objet de "départ" ...

 

On est bien d'accord, et c'est pour ça que GuillaumeB posait la question de l'utilité de leur valeur de retour.

 *Quote:*   

> 
> 
> ```
> >> 10.minutes.ago
> 
> ...

 

Certes, mais ça personne n'a dit le contraire. Il n'y a pas d'effet de bord dans ton exemple (minutes retourne un nouvel entier, etc.), donc là y'a pas à tortillier : appliquer des méthodes directement sur le retour d'autres méthodes, c'est normal et c'est très bien (et on le fait souvent en Python aussi, quand même...). Ça n'est que si il y a des modifications d'objets de planquées au milieu que c'est discutable (et qu'on en discutait).

 *Quote:*   

> Oui et non ... ce n'est pas seulement une facilité d'écriture mais plutôt IMHO de lecture ainsi que de "localité de code" (on groupe ce qui va fonctionnellement ou logiquement ensemble)

  Oui, je suis d'accord.

 *Quote:*   

> Hummm ... je préfère 
> 
> ```
> puts a.join(",") unless a.compact!.nil?
> ```
> ...

 

Mouais, on n'a pas visé le même cas en fait : 

 - moi je supposais que le tableau a n'était pas vide, mais pouvait contenir des nil, et je voulais ne l'afficher que si il contenait au moins un vrai élément (et donc si le compact renvoyait un truc de longueur non nulle).

 - toi tu supposes que a peut être vide, et que donc le compact peut renvoyer nil, et c'est seulement dans ce cas que tu zappes l'affichage. Mais par contre tu vas afficher une string vide si a est, par exemple, [nil,nil,nil].

Mais bref, quoi qu'il en soit, la question posée par mon exemple était plutôt de savoir si il est bon ou non d'utiliser le retour d'une méthode modifiante comme un cas de test. Toi là tu le fais, et moi j'hésite... Enfin en fait, en ce qui me concerne, ça dépend de ce qui se passe ensuite : si on se ressert du a compacté, je préfère isoler le a.compact! sur une ligne avant, histoire qu'il soit bien explicite. Si par contre c'est une modification qui n'a servi que pour le test et l'affichage, et qu'ensuite on ne se ressert plus de a, alors je fais plutôt du tout en un (ma 2nd solution ou une des tiennes, selon ce qu'on veut faire exactement) parceque ça va effectivement ensemble (ça rejoint ta notion de regroupement fonctionnel ou logique).

----------

## Sleeper

 *TGL wrote:*   

> 
> 
> Mais bref, quoi qu'il en soit, la question posée par mon exemple était plutôt de savoir si il est bon ou non d'utiliser le retour d'une méthode modifiante comme un cas de test. Toi là tu le fais, et moi j'hésite... Enfin en fait, en ce qui me concerne, ça dépend de ce qui se passe ensuite : si on se ressert du a compacté, je préfère isoler le a.compact! sur une ligne avant, histoire qu'il soit bien explicite. Si par contre c'est une modification qui n'a servi que pour le test et l'affichage, et qu'ensuite on ne se ressert plus de a, alors je fais plutôt du tout en un (ma 2nd solution ou une des tiennes, selon ce qu'on veut faire exactement) parceque ça va effectivement ensemble (ça rejoint ta notion de regroupement fonctionnel ou logique).

 

Je le fais pour l'exemple ... dans mon code je ne le fais pas  :Smile:  Je te rejoins totalement su rl afaçon de l'utiliser  :Wink: 

----------

## kopp

Pour ma part, c'est du script BASH, ou des fois FISH (ça diffère légèrement du coup je m'embrouille à chaque fois)

J'ai jamais eu besoin d'autre chose, donc je ne m'y suis pas plongé... 

Le script, ça fait parti des choses que je dois faire... mais la liste est longue, et se remplit plus qu'elle ne diminue.

----------

## penguin_totof

salut a tous!

 interessant ce thread, voila deux bout de scripts plus ou moins utile:

pour obtenir un Eterm avec de la transparence et une couleur aleatoire. (et ne me demandez pas pourquoi j'ai fait ca en perl, j en sais rien  :Smile:  )

ca ne sert a rien, c est juste un peut plus joli qu'un terminal tout blanc ou noir  :Wink: 

```

#!/usr/bin/perl -w

use strict;

my $greentint = rand(300);

$greentint = int($greentint);

my $redtint = rand(300);

$redtint = int($redtint);

my $bluetint = rand(300);

$bluetint = int($bluetint);

system "Eterm --trans --cmod-green $greentint --cmod-red $redtint --cmod-blue $b

luetint -x --buttonbar 0 --scrollbar 0";

```

ou encore quelques lignes dans le .bashrc pour faciliter le montage/demontage des peripheriques amovibles (pour ceux qui ne veulent pas s'emm***** avec le montage automatique, hal/dbus ou je ne sais quoi qui n'as jamais fonctionne a 100% chez moi  :Wink:  . Simple mais efficace )

```

#alias de montage de peripheriques amovibles

alias mountfloppy="mount /dev/fd0 && cd /mnt/floppy/ && echo \"Floppy disk mounted successfully on /mnt/floppy...\" && echo \"floppy disk contains:\" && ls -l /mnt/floppy/"

alias umountfloppy="sync && cd ~/ && umount /dev/fd0 && echo \"Floppy disk unmounted successfully...\""

alias mountusb="mount /dev/sda1 && cd /mnt/usbkey/ && echo \"USB Key mounted successfully on /mnt/usbkey...\" && echo \"USB Key contains:\" && ls -l /mnt/usbkey/"

alias umountusb="sync && cd ~/ && umount /dev/sda1 && echo \"USB Key unmounted successfully...\""

alias mf="mountfloppy"

alias umf="umountfloppy"

alias mu="mountusb"

alias umu="umountusb"

alias mcd="mountcd"

alias umcd="umountcd"

```

----------

## anigel

 *TGL wrote:*   

> Grosso modo, ce que j'apprécie, c'est que ça se prête bien à une approche incrémentale. On peut faire des trucs déjà utiles et fonctionnels directement sur la ligne de commande, et c'est comme ça que ça commence en général, avec un simple "one-liner". Parfois ça en reste là (j'en fais juste un alias), et parfois ça grossit parceque je l'améliore petit à petit, et alors, pour l'éditer plus facilement, je le colle dans un fichier et je l'indente. Voilà, un script crade est né. 

 

Pas si crade que ça, j'ai d'ailleurs repris voilà déjà un bon moment une de tes créations, que j'ai un peu modifié pour prendre en compte plusieurs arguments : la fonction bash usedesc(). Sans vraiment le vouloir, j'ai fait un peu de récursivité en bash  :Wink: .

```
usedesc () {

        local portdir=$(sed -n 's:^PORTDIR=::p' /etc/make.conf);

        [ -z "$portdir" ] && portdir=/usr/portage;

        [[ ${#} -ge 1 ]] && printf "${__GREEN} ==>> ${__YELLOW}${1}${__GREEN} <<== \n" %s && \

        grep -h "$1.*\ -\ " ${portdir}/profiles/use.* | \

        gawk -F' - ' '{ printf (" \033[32;01m* \033[31;01m%s \033[0;01m- \033[36;01m%s\033[0;0m \n", $1, $2) }'

        if [ ${#} -gt 1 ] ; then

                shift

                echo

                usedesc ${@}

        fi

}
```

----------

## bibi.skuk

tiens, 2 lignes de python, a peine testées, en fait, je me suis demandé lors d'une maj si je pouvais avoir la liste des paquets restants a emerger... voila ce qui en est sorti, c'est pas genial, dans le sens ou je ne suis pas sur que ca marche a tous les coups, l'affichage est tres moche (y'en a pour ainsi dire pas du tout), mais bon, si ca peut servir a quelqu'un. j'essayerait de le modifier un peu histoire d'en faire un script utilisable.

```

#!/usr/bin/python

import portage

mergelist = portage.mtimedb["resume"]["mergelist"][:]

for x in mergelist: print x[2]

```

Oui, je l'avait dit que c'etait basique... (mais ca m'a donné envi de regarder un peu plus attentivement comment fonctionne portage  :Smile:  )

----------

## Trevoke

On en est a presque un mois, je dirais que ce thread est epuise, non?

----------

## yoyo

 *Trevoke wrote:*   

> On en est a presque un mois, je dirais que ce thread est epuise, non?

 On est en pleine discussion à ce propos ...

Le prochain devrait arriver incessamment.   :Rolling Eyes: 

----------

## Darkael

 *yoyo wrote:*   

>  *Trevoke wrote:*   On en est a presque un mois, je dirais que ce thread est epuise, non? On est en pleine discussion à ce propos ...
> 
> Le prochain devrait arriver incessamment.  

 

Pourquoi ne pas juste les faire dans cet ordre?

C'est pas comme si certains sujets étaient meilleurs que d'autres  :Confused: 

----------

## anigel

 *KarnEvil wrote:*   

> Pourquoi ne pas juste les faire dans cet ordre?

 

Disons, pour faire simple, que nous essayons de privilégier les sujets "à fort potentiel". Mais c'est assez subjectif, c'est vrai  :Wink:  !

----------

## Trevoke

J'veux pas troller, hein, mais "A mort louis croix veh baton".

Comment ca, je sais pas faire autre chose que troller? Non mais dis donc.   :Embarassed:  Demasque!

Serieusement, allez, je veux apprendre un peu plus moi!

----------

## Mickael

Bonjour,

alors pour moi c'est la première fois que je me mets à ces petits scipts qui rendent la vie plus facile. J'ai donc récupérer un premier squelette d'un script bash pour de la sauvegarde de données. Je fais donc un tar, puis un tar --diff ou compare (c'est là que j'aimerais un coup de main, en effet je ne sais pas récuper les alertes qui en découlent afin de stopper l'opération de transfert qui est censée suivre) puis je transfert avec smbclient :

```

#!/bin/bash

        # Crée une sauvegarde compressée de tous les répertoires spécifiés et stocke

        # le fichier en résultant dans un répertoire de votre choix.

        #SAUVE_REP="$HOME /etc /var"

        SAUVE_REP_PERSO="/home/mickael/Articles /home/mickael/Presentation /home/mickael/Publications_Personnelles"

        #NOM_SAUVEGARDE=`date '+%b%d%Y'`

        NOM_SAUVEGARDE="Backup.tar.gz"

        SAUVEGARDE_DEST_REP="/home/mickael/Gentoo/Backup"

        # Décommentez la ligne suivante pour obtenir une sauvegarde GZippée,

        # commentez pour une sauvegarde BZippée

        echo "Compression des dossiers avant transfert"

        tar czfP $SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO

        echo "Comparaison de l'archive avec les répertoires courants..."

        #tar --diff --verbose --file=$SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO

        tar --diff  --file=$SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO /home/mickael/Gimp/

(ici j'ai rajouter un répertoire que je ne sauvegarde pas afin d'avoir une comparaison avec erreur!

        # Nous créons une archive BZippée...

        # Commentez la ligne suivante pour une archive GZippée,

        # décommentez pour une archive BZippée

        #tar cjf $SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE.tar.bz2 $SAUVE_REP

        # Connexion avec LAB-SERVEUR

        echo "Sauvegarde en cours sur le serveur..."

        echo "Vous pouvez prendre un café..."

        smbclient "//X.X.X.X/Sauvegardes" -U xxx%xxxx -D xxxxx/backup -c 'put /home/mickael/Gentoo/Backup/Backup.tar.gz Backup.tar.gz'

```

voili voilà, c'est pas encore dans cron, mais le petit grandi.  :Wink: 

PS : j'oubliais de vous montrer une alerte :

 *Quote:*   

> ./Gentoo/Backup/save.sh
> 
> Compression des dossiers avant transfert
> 
> Comparaison de l'archive avec les répertoires courants...
> ...

 

PSS : Pourquoi ce langage : et bien je sais pas, la première fois c'était du bash également je n'ai fait que recopier un script pour ma carte pcmcia. De plus, les exemples trouvés sur le net pendant mes recherches étaient également en bash, et je le trouve assez simple ou plutôt il me semble accessible pour moi.

----------

## Mickael

Juste une petite évolution de script pour sauvegarde.

Afin d'avoir une archive tar datée j' ai donc modifier ceci : 

```
 NOM_SAUVEGARDE=`date '+%b.%d.%Y'.tar.gz`
```

Jusque là vous me direz rien de bien méchant, certe, mais le problème c'est que smbclient lui il aime bien les noms de fichiers soient correctement arrêtés,  en gros on peut pas mettre $NOM_SAUVEGARDE à  la fin du "put" (put est une option de smbclient). Donc l'astuce est d'utiliser les mask et mput ce qui donne :

```

cd $SAUVEGARDE_DEST_REP

# Connexion avec LAB-SERVEUR

        echo "Sauvegarde en cours sur le serveur..."

        echo "Vous pouvez prendre un café..."

        smbclient "//x.x.x.x/xxxxxx" -U x%xxxxx -D xxxx/backup -c "mask /home/mickael/Gentoo/Backup/TEST/*.2006.tar.gz ;  mput *.2006.tar.gz"

```

Voui, vous me dite que si vendredi prochain je fais une sauvegarde, il va de nouveau me transférer celui d'aujourd'hui, mais rien ne nous empêche de déplacer ce dernier avec un mv!.

----------

## AigleFR

```

### A savoir: ce script se connecte automatiquement au reseau wifi detecte (s'il est configure).

### Le script cherche d'abord dans le fichier des reseaux prioritaires (on y classe les réseaux par nom ESSID et par ordre de priorité)

### Si il ne trouve aucun reseau prioritaire, il cherche dans le dossier qui contient tous les reseaux configurer, et là il se connecte au premier qu'il trouve.

### Dans le dossier des fichiers de configurations de tous les reseaux auxquels on peut se connecter, il faut mettre comme nom de fichier, 

### celui de son ESSID (ex: si mon ESSID est Wanadoo_1234, le fichier s'appelera Wanadoo_1234) 

### Il peut etre pratique de mettre un lien dans /sbin vers le répertoire ou se trouve le script 

### (ex: dans /sbin un lien appelle wifi qui point vers /home/tux/script/script_connection_wifi)

### Ainsi, il suffira de lancer par exemple la commande wifi pour lancer le script.

#!/bin/bash

######## ICI se trouve la configuration du script ########

connectdefaut="/home/utilisateur/script/wifi/defaut.conf"     #fichier de config par defaut

connectprio="/home/utilisateur/script/wifi/prio.conf"         #fichier contenant les ESSID prioritaires

dossres="/home/utilisateur/script/wifi/config/*"              #dossier ou se trouve les fichiers de config

dossres2="/home/utilisateur/script/wifi/config/"              #dossier ou se trouve les fichiers de config

ipdef="192.168.1.51"    #adresse ip par defaut si dhcpcd echou ou si on prefere utilise une ip statique pour se connecter

ippass="192.168.1.1"     #adresse ip de la passerelle (exemple 192.168.1.1 pour une livebox)

inter="eth1"             #interface reseau wifi

driver="ipw2200"         #driver de la carte wifi

wifires="/home/utilisateur/script/wifi/wifires"            #pour mettre les reseaux trouves

wifirestmp="/home/utilisateur/script/wifi/wifirestmp"      #pour faire une petite transformation

wifirestmp2="/home/utilisateur/script/wifi/wifirestmp2"    #pour faire une petite transformation

############################################################

##### Commande a lancer en tout premier #####

echo " "

#############################################

#############################################

test() {

if lsmod | grep "$driver" > /dev/null

    then

         echo " * Driver OK"

     else

         echo " * Driver $driver non trouvé"

         echo "   * Lancement du driver"       

        if modprobe "$driver"                  

           then                    

                echo "     * Driver $driver lance"

      sleep 2

           else

                echo "     * Impossible de lancer le driver $driver"

      exit

        fi

    fi

scanres=$(iwlist "$inter" scanning | grep ESSID)

stop-wpa > /dev/null

stop-dhcpcd > /dev/null

}

#############################################

scan() {

echo " * Detection des reseaux actifs"

sleep 2      

if [[ ! $scanres ]]

  then

    echo "   * Aucun reseau detecte"

    exit

  else

    echo > "$wifires"

    echo > "$wifirestmp2"    

    echo "${scanres}" > "$wifirestmp"

    

    for anter in $(cat "$wifirestmp")

      do

        echo "$anter" >> "$wifirestmp2"

   echo $(cut --delimiter='"' -f2 "$wifirestmp2") >> "$wifires"

      done

    echo -n "   * Reseaux detectes : "

    echo $(cat "$wifires")

fi

}

#############################################

auto() {

      

echo " * Connection au reseau"

      

for wifitrouv in $(cat "$wifires")

  do

    

    for wifirechdef in $(cat "$connectprio") #recherche d'abord une connection dans le fichier de config prioritaire     

      do     

        if [ "${wifirechdef##*/}" = "$wifitrouv" ]

          then

       config="$dossres2""$wifirechdef"

       connect

   fi

      done    

    echo "   * Aucun reseaux prioritaire trouves"

    for wifirech in $dossres #recherche ensuite dans le dossier des fichiers de config      

      do

        if [ "${wifirech##*/}" = "$wifitrouv" ]

          then

       config="$wifirech"

       connect

       exit      

        fi

      done

  done

echo " "

echo " * ERREUR: Aucun fichier de configuration ne correspond au reseau trouve"

      

exit

}

#############################################

connect() {

echo " * Debut de la connection"

connect-wpa

connect-dhcp

}

############################################

connect-wpa() {

echo "   * Connection au reseau : "${config##*/}" "

echo "   * Lancement de wpa_supplicant ... "  

if [[ $(wpa_supplicant -Dwext -ieth1 -c"$config" -B -w) ]]

  then

    echo " "

    echo "   * ERREUR: Impossible de lancer wpa_supplicant"

    exit

fi

}

#############################################

connect-dhcp() {

##Si on ne veut pas utiliser une ip automatique avec dhcpcd, il faut commenter cette partie, ainsi que le "fi" indiqué

##Ensuite il faut commenter tous les stop-dhcpcd, sauf la fonction stop-dhcpcd()

###############################################################################

echo "   * Lancement de dhcpcd ... "                     #

if dhcpcd "$inter"                           #   

  then                                 #

    echo " * Connection termine"                     #

    sleep 1                              #

    clear                              #

    exit                              #

  else                                 #

    echo " "                              #

    echo "   * ERREUR: Impossible de lancer dhcpcd"               #

    echo " "                              #

###############################################################################     

    

    echo "     * Connection avec une ip statique : $ipdef "            

    if [[ $(ifconfig "$inter" "$ipdef") ]]

      then

        echo "       * ERREUR: Connection avec une ip statique impossible"

   exit

      else

   echo "       * Connection avec une ip statique etablie"         

    fi

   

    if [[ $(route add default gw "$ippass") ]]

      then

        echo "       * ERREUR: Erreur lors de la specification de la route"

   exit

      else

   echo "     * Etablissement de la route par defaut"

   echo " * Connection termine"

        sleep 2

        clear

        exit         

    fi

         

fi ## Commenter ici aussi pour ne pas utiliser dhcpcd

}

#############################################

stop-dhcpcd() {

if [[ $(start-stop-daemon --stop --name dhcpcd) ]]

  then

    echo " * Le service dhcpcd est deja arrete"

  else

    echo " * Arret du service dhcpcd"   

fi

}

#############################################

stop-wpa() {

      

if [[  $(start-stop-daemon --stop --name wpa_supplicant) ]]

  then

    echo " * Le service wpa_supplicant est deja arrete"

  else

    echo " * Arret du service wpa_supplicant"

fi      

}

#############################################

#############################################

case $1 in

   start) #pour se connecter a la config de defaut

      test

      config="$connectdefaut"

      connect

      ;;

   stop)

      stop-wpa

      stop-dhcpcd

      ;;

   auto)

      test

      scan

      auto

      ;;

   restart)

      stop-wpa

      stop-dhcpcd

      test

      scan

      auto

      ;;

   force) #pour specifier le chemin et le nom du fichier de config (ex: wifi force /home/tux/script/config/Wanadoo_1234 )

      test

      config="$2"

      connect

      ;;

   scan)  #pour detecter seulement les reseaux sans s'y connecter

      test

      scan

      exit

      ;;

   *)

      if [ ! $1 ] # Si aucune option, on lance auto par defaut 

         then

            test

            scan

            auto

      fi

      echo " "

      echo " * ERREUR : Commande inconnue"

      exit

      ;;

esac

```

En gros, c'est un script qui permet de se connecter automatiquement avec wpa_supplicant sur réseau wifi qui est détecté (à condition que se réseau soit déjà configurer).

C'est pratique quand on doit se connecter sur différent réseaux wifi à différent endroit.

Je pense q'on peut facilement améliorer le script et aussi rajouter des fonctions.

PS: Désolé pour la taille du script ... et j'espère qu'il sera utile a quelqu'un.

----------

## Mickael

Bonjour,

toujours dans la continuité de mon petit script bash pour faire de la sauvegarde, j'ai un petit problème avec tar et la redirection des erreurs dans un fichier intitulé erreurs.log :

```
echo "Comparaison de l'archive avec les répertoires courants..."

        tar --diff  --file=$SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO $REPERTOIR_TESTING > $ERREURS_LOG
```

Mon problème est qu'il ne va jamais écrire dans ce fichier représenté ici par la variable $ERREURS_LOG. Afin d'avoir des erreurs, j'ai rajouté un répertoire/fichier définit par $REPERTOIR_TESTING. Dans une console, il me dit bien que dans l'archive tar, il n'y a pas les fichiers qui appatiennent à $REPERTOIR_TESTING, mais le fichier erreurs.log lui est vide, désespérément vide...

Elle est où la boulette s'il vous plaît?

----------

## Oupsman

Ta redirection n'est pas bonne, tu ne rediriges que la sortie standard, pas la sortie d'erreur.

Essaye ceci :

```

echo "Comparaison de l'archive avec les répertoires courants..."

        tar --diff  --file=$SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO $REPERTOIR_TESTING 2> $ERREURS_LOG

```

Perso, dans mes scripts je fais :

```

commande > fichier.log 2>&1 

```

pour rediriger la sortie d'erreur vers la sortie standard

----------

## Mickael

Merci Oupsman, je test de suite et je me renseignerai par rapport à ta technique des 2>&1.

EDIT : Merci, cela fonctionne maintenant. Alors jevous montre la toute petite évolution de mon script :

```

#!/bin/bash

clear

        SAUVE_REP_PERSO="/home/mickael/Articles /home/mickael/Presentation /home/mickael/Publications_Personnelles"

        NOM_SAUVEGARDE=`date '+%b.%d.%Y'.tar.gz`

        SAUVEGARDE_DEST_REP="/home/mickael/Gentoo/Backup/TEST"

        ERREURS_LOG="/home/mickael/Gentoo/Backup/TEST/erreurs.log"

        REPERTOIR_TESTING="/home/mickael/Conneries"

        > $ERREURS_LOG

        # Décommentez la ligne suivante pour obtenir une sauvegarde GZippée,

        echo "Compression des dossiers avant transfert"

        tar czfP $SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO

        echo "Comparaison de l'archive avec les répertoires courants..."

        tar --diff  --file=$SAUVEGARDE_DEST_REP/$NOM_SAUVEGARDE $SAUVE_REP_PERSO $REPERTOIR_TESTING 2> $ERREURS_LOG

        if test -s '/home/mickael/Gentoo/Backup/TEST/erreurs.log';

                then

                        echo    "               $(color ltyellow red)RAPPORT DE L'OPÉRATION$(color off)"

                        echo    "$(color ltyellow red)!ERREUR/ Les fichiers suivants sont absents de l'archive :$(color off)"

                        cat < $ERREURS_LOG

                        exit

                else

                        echo  "********************************"

                        echo  "*        $(color ltgreen black)RAPPORT DE L'OPÉRATION$(color off)*"

                        echo  "*          $(color ltgreen black)Archive réussie$(color off)     *"

                        echo  "********************************"

                        # Déplacement dans le fichier de sauvegarde

                        cd /home/mickael/Gentoo/Backup/TEST/

                        # Connexion avec LAB-SERVEUR

                        echo "Sauvegarde en cours sur le serveur..."

                        echo "Vous pouvez prendre un café..."

                        smbclient "//xxxxxx/Doctorants" -U xxxxx%xxxxx -D mparis/backup -c "mask /home/mickael/Gentoo/Backup/TEST/*.2006.tar.gz ;  mput *.2006.tar.gz"

                        # Une petite phrase.

                        echo "Sauvegarde Terminée !"

        fi

                        # On vire la sauvegarde du PC perso :

                        rm $NOM_SAUVEGARDE

```

EDIT 2 : Ta technique Oupsman, est plus intéressante car en plus d'avoir que les erreurs j'ai également la sortie standard. Ce 2>&1 concatène la sortie d'erreurs sur la sortie standard, mais je crois que dans mon cas, vu la boucle qui suit ce tar --diff, je vais conserver que la redirection de la sortie d'erreurs. Merci encore pour l'info.  :Wink: 

----------

## Oupsman

 :Arrow:  ce lien peut être utile : http://abs.traduc.org/abs-3.7-fr/io-redirection.html

----------

## Mickael

J'ai une question d'ordre générale, qui je pense intéresserait beucoup de débutants lorsqu'ils se lancent dans l'écriture de petits scripts. Comment fait-on, (ou peut-être Où trouver cette info) pour dire au script de ce lancer que si une carte pcmcia est présente par exemple, et par corrolaire de s'arrêter si elle ne s'y trouve plus? Vous voyez ce que je veux dire? 

En fait ma question est double, mais ce que je ne sais pas c'est où trouver l'info qui me dira que la carte pcmcia est bien présente.

Merci.

EDIT : Je pensais  à la commande tail, mais le problème c'est que mon fichier dmesg ou message n' a jamais été éffacé donc il contient beaucoup de lignes, donc le script peut être dupé par une info périmée...oui/non/peut-être.

----------

## kaworu

au risque de dire une erreur :

ça crée un événement acpi d'insérer ou enlever une carte PCMCIA non?

Si c'est le cas, c'est très simple ^____^

mes 2 cents..

----------

## Mickael

 *kaworu wrote:*   

> au risque de dire une erreur :
> 
> ça crée un événement acpi d'insérer ou enlever une carte PCMCIA non?
> 
> 

 

Je le vois comme cela, et si je dis pas de bêtises, on retrouve cette info dans le fichier dmesg/messages (je sais plus   :Embarassed:  ) mais cette dernière info peut être suivie au cours d'une journée par plusieurs infos, sans compter que ces deux fichiers n'ont jamais été néttoyés/vidés!!!! donc le script ou la commande appropriée peut être bernée par un vieux log??  :Confused: 

----------

## Oupsman

Question con : et en passant par le trio dbus/hal/ivman ?

----------

## Mickael

 *Oupsman wrote:*   

> Question con : et en passant par le trio dbus/hal/ivman ?

 

OK mais comment?????? em même temps mon trio c'est : dbus/hal/gvm

----------

## Oupsman

 *MickTux wrote:*   

>  *Oupsman wrote:*   Question con : et en passant par le trio dbus/hal/ivman ? 
> 
> OK mais comment?????? em même temps mon trio c'est : dbus/hal/gvm

 

Après réflexions, je ne sias pas si mon trio est le bon   :Embarassed:   :Embarassed:   :Embarassed: 

----------

## Mickael

Pourquoi? il est bon ton trio, ivman gvm et autres c'est une question de choix, d'indépendance et je ne sais quoi.

----------

## Mickael

Bon, alors je viens de lire quelques infos (voir ici) sur la toile et je dirais que udev suffirait à notre bonheur :

1 : insertion du périférique, sans rien toucher à udev, sa config etc...

2 : vérification dans /var/log/syslog du ou des périfériques créés par udev.

3 : c'est udevinfo qui va nous fournir le chemin complet dans /sys dans lequel ontrouvera toutes les infos relatives à notre périférique.

4 : Un extrait de dmesg avec l'insertion de ma carte, @Kaworu : on a bien l'événement acpi mais est-il écrit ailleurs :

 *Quote:*   

> pccard: card ejected from slot 0
> 
> ndiswrapper: device wlan0 removed
> 
> ACPI: PCI interrupt for device 0000:03:00.0 disabled
> ...

 

5 : Je crois bien que udev suffira à notre bonheur si pcmciautils à été compilé pour communiqué avec udev. Si j'ai bien compris la documentation, par défaut c'est udev qui se chage du boulot.

6 : Une solution : utilisée la réponse de la commande pccardctl status : exemple sans carte insérée :

```
Socket 0:

  no card
```

----------

## olivier elmekki

Bonjour,

  ma petite contributions à ce thread qui mérite d'avoie la vie longue...

  Il s'agit d'un script permettant de trier les fichiers mp3 d'un répertoire suivant l'une de ses balises, en les plaçant dans un répertoire du nom de la valeur de la balise choisie.

  J'ai choisi ruby car c'est mon langage usuel. C'est vrai que ces 'quick-hacks' ne permettent pas trop d'utiliser le modèle orienté-objet de ruby, mais comme un autre de ses atouts est la concision et qu'il permet tout de même de faire de la programmation impérative, je le préfère généralement à bash (qui reste pourtant, selon moi, un modèle de langage intégré à un systême).

  A noter que pour faire tourner ce script, il faut bien sûr l'interpréteur ruby, mais aussi le module mp3info (dev-ruby/ruby-mp3info).

```

#!/usr/bin/env ruby

require 'mp3info'

require 'fileutils'

case ARGV[0]

when 'artist', 'genre', 'comments', 'title', 'album', 'tracknum'

    Type_tri = ARGV[0]

else

    puts "\

synopsis: tri_mp3.rb type_tri [chemin]

où type_ tri peut être, au choix:

    artist, genre, comments, title, album, tracknum

tri_mp3 permet de classer des fichiers musicaux en les placant dans un répertoire suivant un critère commun que vous

aurez choisi, sur la base d'une balise mp3.

  Si 'chemin' n'est pas spécifié, tri_mp3.rb sera lancé dans le répertoire courant."

end

chemin = ARGV[1]

if chemin != nil and File.directory?( chemin )

    chemin += '/' if chemin[/\/$/] == nil

    repertoire = Dir.new( chemin )

else

    repertoire = Dir.new( './' )

end

str_rep = repertoire.path

repertoire.each { |fichier|

    if File.extname( fichier ) == '.mp3'

        f_mp3 = Mp3Info.new( fichier )

        balise = f_mp3.tag[ Type_tri ]

        balise = f_mp3.tag2['TCON'] if Type_tri == 'genre' and balise == nil

        balise = 'inconnu' if balise == nil

        Dir.mkdir( str_rep + balise ) if not File.exist?( str_rep + balise )

        FileUtils.mv( str_rep + fichier, str_rep + balise + '/' + fichier )

    end

}

```

----------

## Mickael

J'ai une petite question pour les utilisateurs de sed. JE suis en train de faire mumuse, avec sed suite à ce poste, mais également à une demande sur la section portage du forum. Un utilisateur y demande si il était possible de gérer les flags USE par catégories dans etc-portage.package.use avec une écriture particulière, la réponse est pour le moment non. Mais il est possible de faire un petit script, genre on commence par retrouver dans une catégorie tous les ebuilds qui ont la variable USE doc, puis avec sed, on récupère que le début de la sortie de la première commande que l'on ira écrire dans etc/portage.use. 

Commande 1 :

trouver dans /usr/portage/dev-ruby, tous les ebuilds qui ont la variable doc :

```
find ./dev-ruby/ -name '*.ebuild' -exec grep -ni 'IUSE="*doc*"' {} /dev/null ';' 

./dev-ruby/mod_ruby/mod_ruby-1.2.4-r2.ebuild:13:IUSE="doc"

./dev-ruby/mod_ruby/mod_ruby-1.2.4-r1.ebuild:13:IUSE="doc"

./dev-ruby/fxruby/fxruby-1.2.6.ebuild:16:IUSE="doc"

```

Ok, si on redirige tout ceci dans un fichier test, placé dans home, on peut alors faire mumuse avec sed. Mais mon problème est que pour le moment je n'arrive pas à récupérer tout ce qui se trouve entre ./dev-ruby/mod_ruby/ et virer tout ce qui suit, par exemple. pour ensuite aller écrire ceci dans etc/portage/package.use...

Comment fait on svp?

Commande sed 2 :

celle-ce ne va pas :

```
sed -n -e 's/ *[/]//p' /home/mickael/test 

mod_rubymod_ruby-1.2.4-r2.ebuild:13:IUSE="doc"

mod_rubymod_ruby-1.2.4-r1.ebuild:13:IUSE="doc"

fxrubyfxruby-1.2.6.ebuild:16:IUSE="doc"

```

Il faudrait que je remplace l'option p par g, mais les / m'emmerde...

----------

## geekounet

Ça ne marchera pas avec tous les ebuilds, parce que certains ont leurs USE depuis les eclass dont ils héritent.

----------

## Mickael

certes.

----------

## Enlight

 *geekounet wrote:*   

> Ça ne marchera pas avec tous les ebuilds, parce que certains ont leurs USE depuis les eclass dont ils héritent.

 

C'est là que si il est fort il va tracer l'inherit   :Cool: 

Par contre au lieu de te prendre le choux à faire un gros script sed, je recommande chaudement d'utiliser les regexps de perl.

----------

## GentooUser@Clubic

J'utilise beaucoup les scripts   :Very Happy: 

Pour les langages j'ai un peu de tout, du bash principalement mais aussi du python, du perl et du PHP, suivant les envies/besoins.

La j'étudie le zsh et le ruby.

----------

## Kangourou

 *MickTux wrote:*   

> J'ai une petite question pour les utilisateurs de sed. JE suis en train de faire mumuse, avec sed suite à ce poste, mais également à une demande sur la section portage du forum. Un utilisateur y demande si il était possible de gérer les flags USE par catégories dans etc-portage.package.use avec une écriture particulière, la réponse est pour le moment non. Mais il est possible de faire un petit script, genre on commence par retrouver dans une catégorie tous les ebuilds qui ont la variable USE doc, puis avec sed, on récupère que le début de la sortie de la première commande que l'on ira écrire dans etc/portage.use. 
> 
> Commande 1 :
> 
> trouver dans /usr/portage/dev-ruby, tous les ebuilds qui ont la variable doc :
> ...

 

Chuis pas sûr d'avoir compris mais ce genre de truc :

```
grep -Rni 'IUSE="*doc*"' /usr/portage/dev-ruby/ | sed -e 's/\.ebuild.*//g'
```

 ça ira ?

----------

## Mickael

C'est presque ça Kangourou,

mais :

 *Quote:*   

> grep -Rni 'IUSE="*doc*"' /usr/portage/dev-ruby/ | sed -e 's/\.ebuild.*//g'
> 
> /usr/portage/dev-ruby/mod_ruby/mod_ruby-1.2.4-r2
> 
> /usr/portage/dev-ruby/mod_ruby/mod_ruby-1.2.4-r1
> ...

 

ce que je souhaite retirer est encore plus court : dev-ruby/mod_ruby et dev-ruby/fxruby.

Merci pour ton aide.

EDIT : EDIT 2 : non mon edit1 ne fonctionnait pas.

----------

## Kangourou

 *MickTux wrote:*   

> C'est presque ça Kangourou,
> 
> mais :
> 
>  *Quote:*   grep -Rni 'IUSE="*doc*"' /usr/portage/dev-ruby/ | sed -e 's/\.ebuild.*//g'
> ...

 

Ça te derange pas si je fais ça avec awk ?  J'ai du mal avec sed   :Embarassed: 

```
grep -Rni 'IUSE="*doc*"' /usr/portage/dev-ruby/ |awk -F "/" '{printf("%s/%s\n",$4,$5)}' | uniq
```

uniq à la fin pour virer les doublons si tu les veux pas.

----------

## Mickael

Merci kangourou c'est exactement cela que je souhaitais obtenir! awk ne me dérange pas plus que cela, de toute façon je découvre sed et awk.  :Wink: 

EDIT : merci pour l'astuce uniq!

----------

## Kangourou

Pas de quoi  :Smile: 

----------

