[gpocentek ] donc bienvenue à tous sur #u-classroom pour la suite de la survie dans le tty
[gpocentek ] == Le shell : notions avancées ==
[gpocentek ] === Introduction ===
[gpocentek ] Ce cours est une préparation au cours sur le scripting shell. Le scripting en
[gpocentek ] soit n'est pas compliqué, et peu de connaissances sont nécessaires. Mais le
[gpocentek ] scripting fait appel à des notions particulières, également utilisables en dehors
[gpocentek ] des scripts. Ce sont ces notions que nous aborderons aujourd'hui.
[gpocentek ] Notez que je n'utilise pas le terme 'bash' ou 'zsh', mais 'shell' qui a un sens
[gpocentek ] plus large. Tous les shells existants ont des particularités, mais nombre d'entre
[gpocentek ] eux ont un point commun : POSIX. POSIX est un standard qu'il est bon de respecter.
[gpocentek ] Utiliser une syntaxe compatible POSIX dans vos scripts vous permettra de les
[gpocentek ] faire fonctionner sur n'importe quel système d'exploitation unix.
[gpocentek ] pour le cours il vous faut juste une chose, un tty ou un terminal
[gpocentek ] (si vous voulez pratiquer en même temps bien sûr)
[gpocentek ] tout le monde a ça sous la main ?
[Sylvio[ ] oui c'est bon pour moi
[firmane ] yes
[Fantoon ] c'est ok
[gpocentek ] ok, let's start
[Damien- ] oui je prend le terminal (mac)
[Erondael ] bonjour, sorry pour le retard
[beware007 ] c'est bok
[MrFreeze^ ] bonjour
[gpocentek ] Erondael: no problem, tu as juste à démarrer ton terminal et c'est bon
[Erondael ] C'est fait en permanence ;)
[Marzikill ] Bonjour à tous ! (désolé pour le retard.... ;) )
[beware007 ] avec un terminal transparent c'est encore mieux :)
[gpocentek ] je vais passer le chan en modéré pour avoir les log plus clairs pendant les parties théoriques
[gpocentek ] === Interaction d'une commande avec son shell ===
[gpocentek ] Sous unix chaque commande utilisateur lancée est attachée à un shell. Démarrez
[gpocentek ] un terminal, démarrez un programme, fermez le terminal, votre programme
[gpocentek ] quittera également. Le programme fait plusieurs choses :
[gpocentek ] - ce pour quoi il est prévu ;
[gpocentek ] - il peut envoyer des informations sur le terminal ;
[gpocentek ] Pour écrire et lire en utilisant le terminal, on utilisant 3 pseudo fichiers
[gpocentek ] particuliers (appelés descripteurs de fichiers) :
[gpocentek ] - stdin (entrée standard, généralement le clavier), également noté 0 ;
[gpocentek ] - stdout (sortie standard, généralement l'écran), également noté 1 ;
[gpocentek ] - stderr (sortie d'erreur, qui utilise en général l'écran comme stdout, et sert à diffuser des messages d'erreur), également noté 2.
[gpocentek ] ok jusque là ?
[firmane ] oui
[Erondael ] yep
[beware007 ] oui
[Dorian13 ] ok
[Damien- ] ui
[Marzikill ] Uaip.
[risoto ] ok
[devil505 ] ok
[Erondael ] ^^
[illovae ] roger that
[gpocentek ] pour voir ces fichiers vous pouvez faire un ls /dev/pts/
[gpocentek ] vous verrez que je ne mens pas ;)
[Sylvio[ ] ok
[illovae ] go question ? :)
[Erondael ] on te croit ;) Moi il why a juste 0
[gpocentek ] illovae: question ?
[beware007 ] pareil pour moi, je n'ai que 0
[illovae ] ouai moi j'ai 0 1 2 3 4”
[risoto ] j'ai juste 0 ptmx
[illovae ] ouai moi j'ai 0 1 2 3 4
[firmane ] moi 0
[Marzikill ] J'ai juste 0.. :'(
[Damien- ] rien
[illovae ] gpocentek: j'ai 0 1 2 3 4
[illovae ] le 3 et 4 c'est quoi stp ?
[gpocentek ] en fait ça peut dépendre des distributions/OS
[Sylvio[ ] idem moir que 0
[gpocentek ] illovae: tu as 2 fichiers "normaux" ouverts
[Damien- ] moi sous mac c'est pas le mm chemin pas grave
[devil505 ] 0 1 2 sur ma frugalware :p
[illovae ] gpocentek: ah d'accord ok
[beware007 ] que 0 sur ma ubuntu
[Fantoon ] est-ce que tu vas expliquer le 2>&1 ?
[Centuri0 ] 0 1 pour moi
*gpocentek testera sur ubuntu
[Erondael ] Bah ca dépend surtout des fichiers ouverts ;)
[risoto ] 0 sur Fedora
[gpocentek ] je vous expliquerai ça la semaine prochaine du coup ;)
[One_Chance ] sur suse 0 2
[firmane ] ok
[gpocentek ] ok je continue, on pourra revenir là dessus plus tard
[hermier ] t'es sur que /dev/pts/ correspond pas à un terminal système ?
[Erondael ] ^^
[gpocentek ] Voici quelques exemples.
[gpocentek ] Lorsque vous entrez votre login dans un tty (pas dans gdm ou kdm), le programme 'login' lit vos données sur stdin.
[gpocentek ] Le programme 'ls' utilise stdout ou stderr suivant ce qu'il a à dire.
[gpocentek ] $ ls # va écrire sur stdout
[gpocentek ] fichier_1 fichier_2 fichier_3
[gpocentek ] On peut s'assurer de ça en redirigeant la sortie ailleurs que sur l'écran. La 'redirection de flux' s'effectue grâce à l'opérateur '>' :
[gpocentek ] $ ls 1>/dev/null # 1 (donc stdout) est redirigé vers /dev/null
[gpocentek ] Rien n'est listé sur le terminal
[gpocentek ] Le résultat de ls est alors écrit dans le fichier spécial /dev/null (c'est un fichier de type 'caractère' qui se contente d'absorber ce qu'on lui envoie sans rien redonner).
[gpocentek ] pour rappel, le # dans la ligne de commande, et tout ce qui suit ne sont pas pris en compte par le shell, ce sont des commentaires.
[gpocentek ] si on ne donne pas l'opérande de gauche à '>', il utilisera stdout. On aurait donc pu écrire :
[gpocentek ] $ ls >/dev/null
[gpocentek ] est-ce clair pour tout le monde
[gpocentek ] ?
[Erondael ] ce qui donne chez les geeks "parle à /dev/null ma tête est malade" ;)
[devil505 ] :D
[Marzikill ] :D
[beware007 ] Erondael > difficile a casé en soirée :)
[firmane ] XD
[Sylvio[ ] Erondael: très bon !
[Erondael ] ;)
[gpocentek ] Erondael: je la replacerai celle là ;)
[beware007 ] sinon, oui j'ai compris. Et j'apprends en plus je connaissais pas le #
[Spip ] ma tete est /dev/full
[gpocentek ] le système de redirection c'est ok ?
[Sylvio[ ] ok
[beware007 ] yep
[gpocentek ] je continue sur le sujet
[gpocentek ] Les messages d'erreur de 'ls' sont toujours envoyés sur stderr, et la redirection précédente n'a pas d'effet :
[gpocentek ] $ ls fichier_non_existant >/dev/null
[gpocentek ] ls: cannot access fichier_non_existant: No such file or directory
[gpocentek ] (vous pouvez essayer chez vous)
[gpocentek ] On peut aussi "cacher" les messages d'erreur en les envoyant vers /dev/null (rappel : 2 correspond à stderr) :
[gpocentek ] $ ls 2>/dev/null
[gpocentek ] Il est possible d'envoyer la sortie standard et la sortie d'erreur en même temps vers /dev/null :
[gpocentek ] $ ls fichier_non_existant >/dev/null 2>&1
[gpocentek ] On envoie 2, stderr, vers l'adresse de 1 : stdout. Attention à la syntaxe. '&1'
[gpocentek ] représente bien stdout lorsqu'il est placé à droite de '>'. Utiliser '1' sans le
[gpocentek ] '&' aurait redirigé stderr dans un fichier nommé '1'.
[gpocentek ] A la place de /dev/null, on peut bien entendu rediriger stdout ou stderr vers
[gpocentek ] un fichier normal. Il est même possible de concaténer (terme barabre signifiant
[gpocentek ] qu'on ajoute à la suite) la sortie au contenu d'un fichier déjà existant avec >>.
[gpocentek ] $ pwd > fichier
[gpocentek ] $ cat fichier
[gpocentek ] /home/gauvain
[gpocentek ] mardi 28 avril 2009, 00:44:19 (UTC+0200)
[gpocentek ] questions, remarques ?
[Erondael ] ca va toujours
[sliencejeparle ] c koi stderr
[Marzikill ] Donc théoriquement, une_commande >/dev/null 2>&1, n'affiche strictement rien ?
[sliencejeparle ] c'est quoi stderr
[Erondael ] l'erreur standard
[gpocentek ] Marzikill: exactement
[sliencejeparle ] ok
[Marzikill ] En ce cas : echo "!" >/dev/null 2>&1
[Marzikill ] bash: !: event not found
[Marzikill ] ?
[Sylvio[ ] ok pr moi aussi
[gpocentek ] sliencejeparle: tu peux lire le début de la session dans le log (cf topic)
[Marzikill ] Pourquoi j'ai quand même un message d'erreur ?
[beware007 ] gpocentek > quel est l'interet d'une telle manoeuvre : 2>&1 ?
[gpocentek ] Marzikill: ! est un caractère spécial
[Marzikill ] Haaan. Ok.
[illovae ] Marzikill: de même que ?
[sliencejeparle ] comment je fais?
[gpocentek ] sliencejeparle: http://u-classroom.net/logs/2009-07-02-scripting_shell_1.html
[Erondael ] Bon je dois partir... Je lirai le log ;) ++
[Marzikill ] (Rq : si on peut même plus utiliser la ponctuation... ;) )
[sliencejeparle ] http://u-classroom.net/logs/2009-07-02-scripting_shell_1.html
[sliencejeparle ] http://u-classroom.net/logs/2009-07-02-scripting_shell_1.html
[illovae ] Marzikill: échappe ton caratère avec \
[gpocentek ] beware007: disons que si tu rediriges dans /var/cache/truc/bidule/foo/bar tu veux pas taper 2 fois le nom de fichier
[gpocentek ] (désolé)
[Marzikill ] Illovae : Uaip, plus rien ! :D
[beware007 ] gpocentek > ah ok
[gpocentek ] c'est un raccourci en gros
[illovae ] Marzikill: alors c'est passé, tu as plus rien en stdout, tout est parti vers /dev/null ;)
[gpocentek ] ça va pour tout le monde ?
[Datenshi33 ] oui
[beware007 ] oui
[Sylvio[ ] oui oui
[MrFreeze^ ] oui
[One_Chance ] principe ok
[gpocentek ] continuons alors
[gpocentek ] === Codes de retour des commandes ===
[gpocentek ] n'ont que peu d'intérêt, et ils n'indiquent ni l'échec complet ni la réussite
[gpocentek ] du programme. Le code de retour du programme donne plus d'informations. Lorsque
[gpocentek ] le programme a fini sont exécution, une variable particulière qui contient le
[gpocentek ] code de retour est disponible : $?.
[gpocentek ] Sa valeur peut être affichée grâce à la commande 'echo'.
[gpocentek ] Dès qu'une autre commande est terminée, sa valeur change, donc le résultat est
[gpocentek ] dépendant de ce qui se passe précédemment :
[gpocentek ] $ ls
[gpocentek ] fichier_1 fichier_2 fichier_3
[gpocentek ] (ls a réussi à faire ce qu'on lui demande)
[gpocentek ] $ ls fichier_non_existant
[gpocentek ] ls: cannot access fichier_non_existant: No such file or directory
[gpocentek ] 0
[gpocentek ] 0 est le code de retour conventionnel lorsqu'une application quitte en ayant
[gpocentek ] fonctionné correctement. Les codes de retour supérieurs à 0 indiquent qu'une
[gpocentek ] erreur s'est produite. La signification dépend du programme.
[gpocentek ] Si le code de retour est supérieur ou égal à 127, c'est qu'une erreur est
[gpocentek ] survenue au niveau du shell :
[gpocentek ] $ appli_inexistante
[gpocentek ] bash: appli_inexistante: command not found
[gpocentek ] est-ce que ça vous parait clair ?
[Dorian13 ] oui
[firmane ] oui pour moi
[Sylvio[ ] ok aussi
[beware007 ] pour moi, bonne explication
[One_Chance ] bien
[Marzikill ] Donc si stderr n'est pas vide, on aura $? != 0 . Vrai ?
[risoto ] ok
[gpocentek ] mais vous êtes extraordinaires !
[gpocentek ] Marzikill: non justement
[Marzikill ] ?,
[MrFreeze^ ] c'est ça le fameux return 0; du main() dans tous les petits programmes ?
[gpocentek ] c'est toute la nuance entre code de retour et les messages du logiciel
[gpocentek ] Marzikill: certains programmes écrivent tous leurs messages sur stderr, même si ce ne sont pas des erreurs
[illovae ] MrFreeze^: oui ça veut dire, fini toi normalement, simplement
[hermier ] les entrées sortie ainsi que le code de retour sont au bon vouloir du programmeur
[gpocentek ] ça ne veut pas dire que l'exécution ne s'est pas bien passer
[gpocentek ] MrFreeze^: oui c'est ça
[Fantoon ] 2>&1 redirige l'erreur vers l'ecran?
[Marzikill ] gpocentek: Ok !
[gpocentek ] Fantoon: ça redirige vers stdout (1)
[MrFreeze^ ] okok
[gpocentek ] si stdout est lui même redirigé vers un fichier, stderr le sera aussi
[sliencejeparle ] comment consulter le stderr
[gpocentek ] Fantoon: ok ?
[Fantoon ] ok
[gpocentek ] ok ok
[gpocentek ] continuons alors
[hermier ] sliencejeparle: stderr est rediriger via bash dans stdout
[gpocentek ] Pour exécuter 2 commandes à la suite, on peut les séparer par le symbole ";".
[gpocentek ] La 2ème commande sera alors exécutée quel que soit le code de retour de la 1ère.
[gpocentek ] $ ls toto; cd toto
[gpocentek ] ls: ne peut accéder toto: Aucun fichier ou dossier de ce type
[gpocentek ] Il n'existe aucun dossier ou fichier "toto", les 2 commandes ont été exécutées et ont échoué.
[gpocentek ] Les opérateurs && et || autorisent l'exécution conditionnelle d'une commande
[gpocentek ] suivant la valeur du code de retour de commande précédente.
[gpocentek ] L'opérateur && n'exécute sa commande de droite que si celle de gauche a un code
[gpocentek ] de retour égal à 0 (donc si elle s'est correctement terminée). $ ls toto && cd toto ls: ne peut accéder toto: Aucun fichier ou dossier de ce type
[gpocentek ] hum désolé
[gpocentek ] $ ls toto && cd toto
[gpocentek ] ls: ne peut accéder toto: Aucun fichier ou dossier de ce type
[gpocentek ] La 1ère commande s'est terminée sur une erreur, la 2ème n'a pas été executée.
[gpocentek ] L'opérateur || n'exécute sa commande de droite que si celle de gauche a un code
[gpocentek ] de retour différent de 0 (donc si elle s'est terminée sur une erreur).
[gpocentek ] $ cd toto || echo 'ne peut accéder à toto'
[gpocentek ] bash: cd: toto: Aucun fichier ou dossier de ce type
[gpocentek ] Le message envoyé par le echo s'affiche car la 1ère commande a échoué
[gpocentek ] Il est bien entendu possible de chaîner autant d'opérateurs && et || que l'on
[gpocentek ] désire et même de les mélanger dans une même ligne de commande. Les 2 opérateurs
[gpocentek ] ont la même priorité et leur évaluation s'effectue de gauche à droite.
[gpocentek ] (je laisse digérer...)
[gpocentek ] questions ?
[beware007 ] Je dis peut etre une betise mais si je comprends bien on peut utiliser le || comme un if si une erreur survient. (par exemple bien sur)
[gpocentek ] beware007: c'est l'idée oui
[Centuri0 ] gtg. Merci
[beware007 ] gpocentek > Ok merci
[risoto ] il faut donc être sûre du résultat de la preière commande pour utiliser efficacement le bon opérateur ?
[hermier ] c'est une technique souvent employé dans les scripts
[gpocentek ] d'ailleurs dans les scripts && et || sont souvent utilisés de cette manière
[franckb ] mmmhhh, too late
[gpocentek ] risoto: ça permettra à ton script de réagir suivant le résultat de ta première commande
[risoto ] ok
[gpocentek ] ça permet d'afficher un joli message d'erreur ou de réussite par exemple
[illovae ] franckb: dans le topic pour voir le début des logs ;)
[gpocentek ] j'ai conscience que ça peut paraître un peu abstrait comme ça, mais comprendre le principe est nécessaire pour rentrer dans le "vrai" scripting
[gpocentek ] d'autres questions ?
[Datenshi33 ] non
[Marzikill ] Dans le cas "toto && tata || titi" --> si toto plante, c'est titi qui s'execute, et sinon tata, c'est ça ?
[hermier ] non
[gpocentek ] Marzikill: si toto plante, ça s'arrête là
[hermier ] dans il y a priorité de gauche à droite
[franckb ] tiens, les logs en live wia le site, pas mal
[illovae ] franckb: on est des profressionnels ici, faut pas croire :P
[gpocentek ] Marzikill: fais des tests, c'est le meilleur moyen de se rendre compte AMHA
[gpocentek ] hop, passons à la suite, les variables
[Marzikill ] Hum... J'ai compris. ('fin je pense. ;) ).
[gpocentek ] c'est un élément essentiel donc on va y aller tranquillement
[gpocentek ] === Utiliser des variables ===
[gpocentek ] Une variable est une sorte de "case mémoire" qui permet la mémorisation et
[gpocentek ] l'échange d'information. Il existe plusieurs types de variables dans un shell :
[gpocentek ] - les variables prédéfinies : elles sont définies à la connexion au shell et sont accessibles et modifiables à l'utilisateur ;
[gpocentek ] - les variables positionnelles : elles contiennent les paramètres d'un script et sont modifiables par l'utilisateur avec la commande "set" ;
[gpocentek ] - les variables spéciales : elles sont réservées et exclusivement maintenues par le shell ;
[gpocentek ] - les variables utilisateur : elles sont définies par l'utilisateur dans le fichier de configuration du shell ou dans un script.
[gpocentek ] Définir une variable est simple :
[gpocentek ] $ NOM_DE_VARIABLE=mon_texte_ici
[gpocentek ] Et pour rappeler cette variable :
[gpocentek ] $ echo $NOM_DE_VARIABLE
[gpocentek ] mon_texte_ici
[gpocentek ] La commande 'echo' affiche simplement la liste des arguments, en remplaçant les
[gpocentek ] variables par leur valeur.
[gpocentek ] je vous laisse tester un peu ça si vous voulez
[gpocentek ] ou dites moi si ça va, qu'on continue
[sliencejeparle ] a=$x est la meme chose que a=x ?
[hermier ] non
[gpocentek ] sliencejeparle: pas du tout
[hermier ] $x est évalué
[Spip ] il y a aussi les variables d'environnement
[sliencejeparle ] mais dans l'initailisation
[Marzikill ] J'aimerai bien un peu plus d'info sur le "set" (à moins que cela ne vienne après ;) )
[sliencejeparle ] quand je fais x=$/home/moh apres echo $x ca me retourne le contenu
[beware007 ] Je sais pas si tu vas en parler mais il faut préciser que par généralité le nom des variables utilisateur est écrit en majuscule.
[gpocentek ] Marzikill: on en parlera plutôt la semaine prochaîne
[sliencejeparle ] alors?
[gpocentek ] beware007: j'y viens
[hermier ] question bete il y a une methode standard pour savoir si on essaye d'affecter une variable protégée ?
[Marzikill ] Ok !
[beware007 ] gpocentek > Ok, désolé d'avoir anticipé
[gpocentek ] sliencejeparle: $x != x, si ça a marché, tu as eu de la chance
[risoto ] les variables sont donc toutes inscrites dans un fichier, il n'y a pas de variable qui puissent "s'effacer" après fermeture du terminal ?
[gpocentek ] hermier: bonne question, à moins de tester le changement effectif je saurais pas dire
[gpocentek ] risoto: j'y viens après
[sliencejeparle ] parceque quand je fais X=$/var/www et echo $X ca me donne le meme valeur
[risoto ] ok ^^
[gpocentek ] ok, vu les questions je vais continuer :)
[gpocentek ] Une autre syntaxe d'accès aux variable est la suivante :
[gpocentek ] $ echo ${NOM_DE_VARIABLE}
[gpocentek ] mon_texte_ici
[gpocentek ] Cette 2ème notation est utile en cas de concaténation d'une variable avec un texte
[gpocentek ] ou une autre variable :
[gpocentek ] $ arbre=sapin
[gpocentek ] $ echo "un $arbre, des $arbres"
[gpocentek ] (non ce n'est pas un oubli ;)
[gpocentek ] en effet, $arbres n'existe pas, et est donc vide !
[gpocentek ] $ echo "un $arbre, des ${arbre}s"
[gpocentek ] cette vois ci c'est bien $arbre qui est utilisé
[gpocentek ] Il faut faire attention à certaines règles :
[gpocentek ] - les noms de variables ne peuvent contenir que des lettres (majuscules ou minuscules), des chiffres et _ ;
[gpocentek ] - dans l'assignation, il n'y a JAMAIS d'espace à gauche et à droite du = ;
[gpocentek ] - les caractères d'espacement (\n, ' ', \t, ...) sont des caractères spéciaux, et nécessitent un traitement particulier. Par exemple :
[gpocentek ] $ FOO=bar baz
[gpocentek ] bash: baz: command not found
[gpocentek ] Par défaut, le caractère espace est le séparateur de commande.
[gpocentek ] Ici le shell affecte donc la valeur "bar" à la variable "FOO" puis essaie
[gpocentek ] d'exécuter la commande "baz" qui n'existe pas.
[gpocentek ] $ FOO="bar baz"
[gpocentek ] $ echo $FOO
[gpocentek ] Les expressions entourées de "" ou '' sont interprétées comme un tout. C'est un
[gpocentek ] élément particulièrement important, notamment pour comprendre comme sont
[gpocentek ] interprétés les arguments passés aux scripts. Dans ce cas, le caractère espace
[gpocentek ] n'est plus considéré comme un séparateur de commande, mais comme faisant partie
[gpocentek ] de la chaîne affectée à la variable "FOO".
[gpocentek ] je sens qu'il va y avoir des questions ;)
[sliencejeparle ] y'a une type de variable ou tous c'est du string
[gpocentek ] tous des strings, mais qui peuvent êtres "castés" en entier quand il faut
[p3in ] ce sont tous des chaines de caractère ;)
[hermier ] sauf extension du shell
[sliencejeparle ] extention du shell ?
[hermier ] bash connais un type "array"
[gpocentek ] oui ça c'est vraiment lié à bash, c'est pas POSIX
[Zohan ] ok
[Marzikill1 ] Arg, problème technique.
[gpocentek ] ok pour continuer ou vous avez d'autres questions ?
[p3in ] c'est quoi POSIX ?
[hermier ] c'est pour ça que je parle d'extention
[hermier ] c'est une norme qui définie la base d'unix
[gpocentek ] p3in: c'est un standard respecté par la plupart des shells
[gpocentek ] on continue sur les variables ?
[p3in ] ok
[gpocentek ] un autre exemple concernant la gestion des espaces :
[gpocentek ] $ FOO=bar\ baz
[gpocentek ] $ echo $FOO
[gpocentek ] Une autre possibilité est d'utiliser le backslash '\', qui est un caractère dit "d'échappement." Placé devant un caractère spécial, il permet de le traiter comme un caractère normal.
[gpocentek ] Essayez par exemple :
[gpocentek ] $ echo \
[gpocentek ] le retour à la ligne n'exécute pas la commande, mais on passe à la ligne
[gpocentek ] (pour continuer la commande)
[gpocentek ] essayez aussi :
[gpocentek ] $ echo \\
[gpocentek ] ok pour l'échappement ?
[Sylvio[ ] ok
[Dorian13 ] ok
[One_Chance ] ok
[Zohan ] ok
[gpocentek ] d'ac
[Marzikill1 ] Oui.
[gpocentek ] La commande set permet de visualiser toutes les variables définies pour le shell.
[gpocentek ] (variables au sens large, vous risquez d'être surpris si vous exécutez cette commande)
[gpocentek ] La commande unset permet de supprimer une variable :
[gpocentek ] $ arbre=sapin
[gpocentek ] $ echo "un $arbre est un arbre"
[gpocentek ] ($arbre est bien remplacé ici par 'sapin' : les "" n'empêchent pas de traiter les variables (on parle de substitution, ou encore d'expansion du shell))
[gpocentek ] $ unset $arbre
[gpocentek ] $ echo "un $arbre est un arbre"
[gpocentek ] $arbre est bien vide après unset
[gpocentek ] (Notez que contrairement à d'autres langages, une variable non définie n'est pas un problème pour le shell, et n'aboutira pas sur une erreur. Elle a une valeur vide)
[gpocentek ] ok pour set et unset ?
[gpocentek ] j'ai perdu tout le monde ?
[illovae ] non :p
[sliencejeparle ] oui
[Marzikill1 ] Non non, toujours là ;)
[risoto ] j'ai du louper ce détil mais à quoi sert le $ de $arbre
[risoto ] detail
[gpocentek ] risoto: $arbre c'est la variable
[Fantoon ] pour voir uniquement les variable d'environnement il y a une commande?
[risoto ] ah oui ok
[hermier ] Fantoon: env
[gpocentek ] Fantoon: c'est dans le prochain paragraphe
[gpocentek ] ok
[gpocentek ] Vous avez très certainement entendu parler des "variables d'environnement". Ce
[gpocentek ] sont les variables dont le shell fournit une copie à sa descendance, c'est à dire
[gpocentek ] tous les processus qui sont lancés par ce shell.
[gpocentek ] La commande export permet de placer une variable dans l'environnement du shell :
[gpocentek ] $ export arbre=sapin
[gpocentek ] $ animal=chien
[gpocentek ] $ bash # on lance un nouveau shell depuis le shell courant
[gpocentek ] $ echo "un $arbre est un arbre"
[gpocentek ] un sapin est un arbre
[gpocentek ] $arbre a bien été rendu accessible au le sous-shell.
[gpocentek ] $ echo "un $animal est un animal"
[gpocentek ] un est un animal
[gpocentek ] $animal n'a pas été passé, car non exporté au sous-shell
[gpocentek ] on quitte le sous shell avec :
[gpocentek ] $ exit
[gpocentek ] La commande 'env' permet de visualiser toutes les variables d'environnement définies.
[gpocentek ] Il y en a quelques unes qui sont définies dans le fichier de configuration de
[gpocentek ] votre shell.
[gpocentek ] $ env
[gpocentek ] SHELL=/bin/bash
[gpocentek ] PWD=/home/gauvain
[gpocentek ] DEBEMAIL=gpocentek@linutop.com
[gpocentek ] XAUTHORITY=/home/gauvain/.Xauthority
[gpocentek ] arbre=sapin
[gpocentek ] ...
[gpocentek ] Le conteneur 'SHELL' a donc la valeur '/bin/bash'. Certaines de ces variables
[gpocentek ] sont définies par le shell lui même (SHELL par exemple), certaines dans son
[gpocentek ] fichier de configuration, d'autres par des logiciels (XAUTHORITY pour X), ou
[gpocentek ] encore manuellement (DEBEMAIL).
[gpocentek ] ok pour l'environnement ?
[Sylvio[ ] ok
[Marzikill1 ] J'ai enfin découvert le $PATH... :D
[hermier ] gpocentek: tu as un chapitre pour "", '' et `` ?
[gpocentek ] hermier: pas aujourd'hui
[hermier ] ok
[gpocentek ] 'fin pas tout aujourd'hui :)
[gpocentek ] est-ce que vous avez des questions/remarques sur tout ce qui concerne les variables ?
[hermier ] non mais comme tu as parler de '' plus haut, je pensait que tu y viendrait vite
[sliencejeparle ] oui c koi DEBMAIL
[sliencejeparle ] DEBEMAIL
[Dorian13 ] une variable
[gpocentek ] c'est une variables que j'ai défini et dont je me sert pour les paquets debian
[gpocentek ] variable*
[MrFreeze^ ] pour savoir ou envoyer le spam
[Marzikill1 ] Bon, désolé, je vais devoir vous laisser... J'irai voir les logs. ;)
[sliencejeparle ] ah ok ^^
[Spip ] packaging ^^
[gpocentek ] on passe à la suite ?
[Zohan ] oui
[sliencejeparle ] oui
[Marzikill1 ] @ Tous : pour prendre connaissance plus en profondeur, ce merveilleux guide, très précis, et très accessible : http://www.iro.umontreal.ca/~dift3830/IntroProgBash.pdf
[risoto ] ok
[gpocentek ] === Mixer variables et commandes ===
[gpocentek ] L'un des intérêts des variables est de pouvoir récupérer directement les
[gpocentek ] éléments écrits sur stdout et stderr par des commandes. L'assignation de
[gpocentek ] variable se fait toujours de la même manière que pour du texte, en utilisant
[gpocentek ] la syntaxe $() pour l'exécution de la commande :
[gpocentek ] $ dirs=$(ls /boot)
[gpocentek ] $ echo $dirs
[gpocentek ] Le résultat d'une commande peut d'ailleurs être utilisé sans passer par une assignation de variable intermdiaire :
[gpocentek ] On rencontre encore très souvent les symboles `` (backquotes) à la place de $()
[gpocentek ] pour l'exécution d'une commande . Leur utilisation limite les possibilités,
[gpocentek ] puisqu'il est impossible d'imbriquer deux commandes de cette manière. Évitez de
[gpocentek ] les utiliser !
[gpocentek ] ça vous parait clair ?
[MrFreeze^ ] oui
[pein ] oui
[sliencejeparle ] oui
[Zohan ] oui
[gpocentek ] good
[gpocentek ] === Traitement conditionnel des variables ===
[gpocentek ] Une syntaxe particulière permet de traiter une variable suivant son existence :
[gpocentek ] - $var ou ${var} : retourne la valeur de la variable si elle est définie, sinon rien
[gpocentek ] $ var=foo
[gpocentek ] $ echo ${var}
[gpocentek ] $
[gpocentek ] (on a vu ça tout à l'heure déjà)
[gpocentek ] - ${var:-argument} : retourne la valeur actuelle de $var si elle est définie, sinon le résultat de l'expansion de "argument" :
[gpocentek ] $ arg=bar
[gpocentek ] $ var=foo
[gpocentek ] $ echo ${var:-${arg}}
[gpocentek ] bar
[gpocentek ] - ${var:=argument} : retourne la valeur actuelle de $var si elle est définie, sinon retourne "argument" (non expandé) et assigne "argument" à var :
[gpocentek ] $ var=foo
[gpocentek ] $ echo ${var:=bar}
[gpocentek ] bar
[gpocentek ] $ echo $var
[gpocentek ] bar
[gpocentek ] - ${var:+argument} : retourne argument si la valeur de $var est définie, sinon ne retourne rien :
[gpocentek ] $ var=foo
[gpocentek ] $ echo ${var:=bar}
[gpocentek ] $ var=
[gpocentek ] $ echo ${var:=bar}
[gpocentek ] c'est un peu catalogue ça, mais sachez que ça existe
[gpocentek ] pas besoin de connaître par coeur tout de suite ;)
[sliencejeparle ] ${var:=bar}et ${var} c'est kooi la diff
[gpocentek ] sliencejeparle: relis les paragraphes, c'est marqué dedans ;)
[gpocentek ] si c'est ok pour tout le monde j'attaque le dernier paragraphe
[gapz ] (meme pas RTFM, qu'il est poli' ce garcon)
[risoto ] ok
[pein ] lol
[gpocentek ] gapz à l'affut ^^
[gpocentek ] dernier paragraphe alors :)
[Zohan ] ok
[gpocentek ] === Chaînage de commandes avec les pipes ===
[gpocentek ] De nombreuses commandes font une tâche bien précise, mais leur résultat peut
[gpocentek ] nécessiter une nouvelle action. Par exemple vous voulez lister les fichiers d'un
[gpocentek ] répertoire X en ne tenant pas compte des fichiers pdf. Vous pouvez utiliser :
[gpocentek ] $ ls /votre/dossier/X | grep -v \.pdf$
[gpocentek ] `ls` va lister tous les fichiers et va les afficher sur la sortie standard. Le
[gpocentek ] `pipe` (tuyau, noté | ) va alors récupérer la sortie et la renvoyer vers l'entrée
[gpocentek ] standard (stdin). `grep` prend alors le relai pour n'afficher que les fichiers
[gpocentek ] ne terminant pas par .pdf.
[gpocentek ] Le mécanisme des pipes (|) permet d'enchaîner plusieurs commandes, en connectant
[gpocentek ] la sortie standard d'une commande à l'entrée standard de la suivante.
[gpocentek ] Cela permet par exemple d'enchaîner plusieurs commandes pour enregistrer le
[gpocentek ] résultat final dans une variable :
[gpocentek ] $ myname=$(getent passwd $USER | cut -d: -f5 | cut -d, -f1)
[gpocentek ] $ echo $myname
[gpocentek ] Il est possible, grâce à la commande tee, de stocker dans un fichier le résultat
[gpocentek ] intermédiaire d'une commande dans une chaîne de pipes.
[gpocentek ] $ date | tee fichier1 | cut -d" " -f1
[gpocentek ] mardi
[gpocentek ] La commande tee se contente de passer le contenu de son entrée standard vers sa
[gpocentek ] sortie standard, en la stockant au passage dans le ou les fichiers passés en
[gpocentek ] argument.
[gpocentek ] est-ce que c'est pigé le coup des | ?
[pein ] oui
[Zohan ] oui
[One_Chance ] je cois
[risoto ] Où est ce que le fichier est enregistré avec la commande tee ?
[gpocentek ] risoto: là où tu lui dis
[gpocentek ] si c'est juste un nom de fichier c'est dans le dossier courrant
[sliencejeparle ] oui
[risoto ] ok
[pein ] on peut aussi rediriger la sortie vers un fichier ?
[gpocentek ] mais tu peux passer un chemin complet (/tmp/foobar par exempel)
[gpocentek ] pein: à la fin de la chaine ?
[pein ] oui
[gpocentek ] oui tout à fait
[sliencejeparle ] ${var:+bar}et ${var} c'est kooi la diff
[gpocentek ] getent passwd $USER | cut -d: -f5 | cut -d, -f1 > /tmp/mon_nom
[pein ] pour quoi utiliser tee alors ?
[hermier ] pein: > est un "terminateur" d'expression
[gpocentek ] tee te permet de garder dans un fichier les étapes intermédiaires
[pein ] ah ok
[gpocentek ] == Pour finir ==
[gpocentek ] (on fait les choses bien, avec une conclusion)
[gpocentek ] Pour éviter un ennuyant catalogue d'autres possibilités, nous avons préparé un
[gpocentek ] document annexe qui vous donnera des informations additionnelles.
[gpocentek ] Vous trouverez dans ce document :
[gpocentek ] - le traitement des variables ;
[gpocentek ] - les outils standards, non liés directement au shell, mais indispensables pour le scripting.
[gpocentek ] Document pdf : http://u-classroom.net/files/2009-06-02/shell/annexes.pdf
[gpocentek ] Lecture en ligne : http://u-classroom.net/files/2009-06-02/shell/annexes/
[gpocentek ] Et je voudrais remercier didrocks et P'tigruik (qui n'est pas là) qui ont contribué à la préparation du cours !
[gpocentek ] voilà pour le cours de ce soir :)
[Zohan ] un grand merci
[apteno ] pour ce qui est des scripts Bash, ce tuto est trs bien fait aussi ==> http://abs.traduc.org/abs-fr/
[sliencejeparle ] thanks
[alpheb ] merci! :)
[risoto ] merci gpocentek
[pein ] mthanx
[sliencejeparle ] ${var:+bar}et ${var} c'est kooi la diff
[sliencejeparle ] vous pouvez me repondre?
[gpocentek ] je ferai l'annonce demain mais la deuxième session sera jeudi prochain à la même heures pour ceux intéressés
[Sylvio[ ] merci gpocentek
[gpocentek ] sliencejeparle: STP relis le paragraphe sur ça, c'est détaillé dedans
[gpocentek ] merci à vous tous d'être venus ;)
[gpocentek ] si vous avez des questions n'hésitez pas
[hermier ] sliencejeparle: ${var:+bar} renvoie la valeur de ${bar} si je me trompe pas
[gpocentek ] ce soir ou dans la semaine, on est toujours quelques uns à squatter le chan
[alpheb ] hermier: seulement si var existedu moins je crois...
[hermier ] c'est ca
[Dorian13 ] merci pour ce cours
[didrocks ] merci gpocentek :)
[Dorian13 ] c'tait trs clair
[sliencejeparle ] ok
[Zohan ] merci beaucoup
[sliencejeparle ] hiya adios
[hermier ] gpocentek: un petit détail pour chippoté, je suis pas sur que tee soit POSIX
[hermier ] sinon bien ;)
[gpocentek ] tee c'est GNU non ?
[One_Chance ] merci
[hermier ] il me semble bien
[gpocentek ] hermier: tee ça fait parti de corutils oui
[gapz ] iirc tee c'est POSIX
[jeanbon ] si, man 1p tee
[gpocentek ] mais bon, le shell sans les outils gnu c'est comme un vélo sans roues :p
[gapz ] cf. info tee
[gapz ] gpocentek: ou pas :>
[gpocentek ] gapz: oui je sais ce que tu vas dire
[gapz ] GNU c'est qu'un c/c de pas mal d'outil déja existant ;-)
*gapz engage les trolls
*gpocentek kick gapz
[apteno ] gapz, a commence bien
[pein ] merci et à bientôt
[sstv_ ] bonsoir j'ai raté le rdv :(
[gapz ] gpocentek: haha !
[gapz ] man 1posix tee
[gapz ] (pour ceux qui ont les pages de manuels de POSIX installé bien sur)
[hermier ] a ben apparement oui, ça manquait quand j'étais à l'école alors
[gapz ] hermier: une distrib avec un userland un peu old school ? :)