Sommaire: Les entrées-sorties d’une commande UNIX (Guide du KornShell sous UNIX)
INTRODUCTION
Guide d’utilisation du guide
Table des Matières
I. Description
I.1. Introduction : qu’est ce que le shell?
I.1.1. Description
I.1.2. Algorithme simplifié
I.1.3. Les différents shells disponibles
I.2. Qu’est ce qu’un processus UNIX ?
I.3. Format d’une commande UNIX élémentaire
I.3.1. Description
I.3.2. Exemples
I.4. Les entrées-sorties d’une commande UNIX élémentaire
I.5. La manipulation des fichiers
I.5.1. Description
I.5.2. Exemple
I.5.3. Les droits et la manipulation des fichiers
I.5.4. Les liens
1.5.4.1. Les liens physiques
1.5.4.2. Les liens symboliques
I.6. Interprétation d’une commande shell
I.6.1. Etape 1 : Interprétation des séparateurs
I.6.2. Etape 2 : Le caractère spécial quote ’
I.6.3. Etape 3 : Les variables et le caractère spécial anti-quote ou $()
1.6.3.1. Etape 3.1 : Les variables
1.6.3.2. Etape 3.2 : Le caractère spécial anti-quote ‘ ou $( )
I.6.4. Etape 4 : Le caractère spécial double-quote »
I.6.5. Etape 5 : Les caractères spéciaux * [] ? ~ \
I.6.6. Etape 6 : les séquences () et {}
I.6.7. Etape 7 : Les caractères spéciaux ; | && & |
1.6.7.1. caractère ;
1.6.7.2. séquence ||
1.6.7.3. séquence &&
1.6.7.4. caractère &
1.6.7.5. le caractère | ou “pipe”
I.6.8. Etape 8 : Les redirections
I.6.9. Etape 9 : La localisation de la commande
1.6.9.1. Les alias
1.6.9.2. Les fonctions
1.6.9.3. Le path
I.7. Le contrôle des processus
I.7.1. La commande ps
I.7.2. Le contrôle des processus par le clavier
I.7.3. La commande jobs
I.7.4. Les commandes fg et bg
I.7.5. La commande kill
II. Les Expressions
II.1. Les expressions du KornShell
II.1.1. L’expression arithmétique
II.1.2. L’expression générique
II.1.3. L’expression conditionnelle
II.2. Les expressions régulières
II.2.1. Expressions régulières de base ( ER )
II.2.2. Expressions régulières étendues ( ERE )
III. Exemples d’utilisation de commandes
III.1. Quelques fonctions du KornShell
III.1.1. cd, pwd
III.1.2. if
III.1.3. for
III.1.4. la commande “point”
III.1.5. print
III.1.6. set
III.1.7. shift
III.1.8. trap
III.1.9. typeset
III.1.10. unset
III.1.11. wait
III.1.12. whence
III.1.13. while
III.2. Quelques commandes UNIX
III.2.1. awk
III.2.2. basename, dirname
III.2.3. bs
III.2.4. dc
III.2.5. file
III.2.6. find
III.2.7. grep
III.2.8. head
III.2.9. join
III.2.10. nohup
III.2.11. sed
III.2.12. sort
III.2.13. strings
III.2.14. tail
III.2.15. uniq
III.2.16. xargs
IV. Cas types
IV.1. Cas types dans un programme shell
IV.1.1. Comment affecter une variable avec le résultat d’une commande?
IV.1.2. Comment lire un fichier ligne à ligne?
IV.1.3. Comment mettre une trace d’exécution?
IV.1.4. Comment tester si un fichier existe? s’il est vide?
IV.1.5. Comment exécuter une commande sur plusieurs fichiers de mon répertoire?
IV.1.6. Comment additionner ou multiplier deux entiers?
IV.1.7. Comment transformer le contenu d’une variable en majuscules? en minuscules?
IV.1.8. Comment contraindre une variable à une longueur donnée?
IV.1.9. Comment lancer mes propres commandes sans être obligé de spécifier leur chem
solu?
IV.1.10. Comment rediriger les sorties standard et d’erreur vers des fichiers séparés?
IV.1.11. Comment écrire un script qui ait 3 sorties standard?
IV.1.12. Comment dérouter l’exécution d’un programme sur réception d’un signal?
IV.1.13. Comment effectuer une sélection parmi plusieurs solutions (CASE)?
IV.1.14. Comment ôter le suffixe à un nom de fichier?
IV.1.15. Comment associer plusieurs conditions dans un test (IF)?
IV.1.16. Comment se débarrasser de messages d’erreurs qui ne m’intéressent pas?
IV.2. Cas types avec la ligne de commande
IV.2.1. Comment bénéficier des facilités de l’historique des commandes?
IV.2.2. Comment retrouver une commande contenant un mot particulier?
IV.2.3. Comment étendre le nom d’un fichier que l’on est en train de taper?
IV.2.4. Comment lancer une commande sans avoir à attendre sa fin?
IV.2.5. Comment lancer une commande qui ne soit pas tuée si on se déconnecte?
IV.2.6. Comment se replacer dans le répertoire que l’on vient de quitter?
IV.2.7. Comment lister les variables positionnées? celles exportées?
IV.2.8. Comment mettre le répertoire courant dans le prompt?
IV.2.9. Comment écrire un alias?
IV.2.10. Dans quel fichier faut-il déclarer les variables et les alias pour les avoir positionn
chaque session?
IV.2.11. Comment lancer une commande avec le contenu du buffer de la souris?
IV.2.12. Où trouver la liste des caractères ascii?
IV.2.13. Comment lister les fichiers par ordre de taille?
IV.2.14. Que faire lorsque le shell refuse d’afficher le “prompt” et d’exécuter mes comma
après chaque retour chariot?
IV.2.15. Pourquoi la sortie d’écran continue t-elle de défiler alors que je viens de taper plus
fois <control>C?
IV.3. Cas types avec les commandes UNIX
IV.3.1. Comment trier un fichier sur le 3ème champ?
IV.3.2. Comment trier un fichier sur plusieurs champs?
IV.3.3. Comment rechercher un fichier dans mon arborescence?
IV.3.4. Comment exécuter une commande sur une liste de fichiers?
IV.3.5. Comment exécuter une commande sur tous les fichiers de mon arborescence?
IV.3.6. Dans un fichier, comment supprimer les lignes dont les 2 derniers champs sont id
ques?
IV.3.7. Dans un fichier trié, comment conserver une seule ligne parmi celles dont le 2èm
champ est identique?
IV.3.8. Comment convertir un nombre décimal en hexa?
IV.3.9. Comment lancer une commande à une date donnée?
IV.3.10. Comment retrouver les fichiers qui n’ont pas été modifiés depuis plus de trois jo
depuis moins de 3 jours?
IV.3.11. Comment extraire les 4ème et 5ème champs des lignes de mon fichier?
IV.3.12. Comment garder toutes les lignes de mon fichier qui ne contiennent pas une cha
particulière?
IV.3.13. Comment recopier un répertoire entier?
IV.3.14. Comment retrouver les fichiers qui font un lien sur un fichier donné?
IV.3.15. Pourquoi je n’arrive pas à supprimer mon fichier? à en créer un?
IV.3.16. Comment positionner par défaut les droits d’un fichier ?
IV.3.17. Comment déterminer le type ou le contenu d’un fichier?
IV.3.18. Comment avoir la réponse à une question qui n’apparait pas ci-dessus?
V. Optimiser un programme shell
V.1. Coût d’exécution
V.2. Quelques conseils en vrac
V.3. Exemples pour éviter les boucles
V.3.1. Recherches de chaînes
V.3.2. Manipulation d’une partie de ligne
VI. Ecrire un programme shell propre
VI.1. Pourquoi perdre du temps?
VI.2. Choix du shell à utiliser
VI.3. Où mettre le nouveau programme
VI.4. Commentaires, version
VI.5. Test des options, vérification des arguments
VI.5.1. Test de la présence des options et paramètres
VI.5.2. Test de la validité des paramètres
VI.6. Entrée standard et/ou fichiers nommés
VI.7. Manipulation des fichiers temporaires
VI.8. Traitements des signaux
VI.9. Emission des messages d’erreur
VI.10. Génération du code de retour
VII. Quelques messages d’erreur courants
VII.1. Format du message
VII.2. Liste des principaux messages d’erreur
VIII. Spécificités SUN-OS 5.1
IX. Spécificités AIX 3.2
INDEX
Bibliographie
Extrait du cours les entrées-sorties d’une commande UNIX (Guide du KornShell sous UNIX)
I.1. Introduction : qu’est ce que le shell?
I.1.1. Description
Le shell est un interpréteur de commandes. Il permet de lancer les commandes UNIX disponibles sur votre station, en leur affectant un certain nombre de paramètres d’exécution, de contrôler les données d’entrée et de sortie, les messages d’erreur éventuels, et surtout de les enchaîner de manière efficace et pratique.Un shell est démarré pour chaque console ouverte (ou fenêtre X11 équivalente créée) ; il est intéractif dans ce cas, car les lignes de commande tapées au clavier sont exécutées une par une avec confirmation systématique (touche <return>).
Un shell est également créé chaque fois que la commande à exécuter se trouve être un fichier ascii : le shell lit successivement toutes les lignes du fichier, supposant que ce sont des commandes ; il disparaît (“rend la main”) une fois la fin de fichier atteinte.
I.1.2. Algorithme simplifié
Si le shell est intéractif, on peut représenter son fonctionnement sous la forme de l’algorithme simplifié suivant :
TANT QUE < durée de la connexion>
lire_ligne_au_clavier(ligne)
traiter_ligne(ligne)
afficher_resultats()
afficher_prompt()
FIN TANT QUE
Si le shell n’est pas intéractif, alors on peut considérer qu’il est lancé directement à travers la fonction traiter_ligne() dont le paramètre est le nom du fichier à traiter ;
I.1.3. Les différents shells disponibles
Le shell est lui même un fichier binaire, qu’il est possible de lancer comme n’importe quelle autre commande UNIX. Ainsi, lorsqu’on parle du “shell”, cela recouvre en fait un ensemble de trois interpréteurs différents, possédant chacun un exécutable spécifique :
i. Le BourneShell, (commande “sh”), est l’original, le plus ancien ayant existé sous UNIX ; c’est celui qui possède aussi le moins de fonctionnalités, et qui est le moins pratique à utiliser ; par contre, on est sûr de le trouver quelque soit le type de machine.
ii. Le Csh (commande “csh”), est plus récent et intègre des fonctions supplémentaires comme l’historique des commandes, indispensable en usage courant ; on le trouve en standard sur la plupart des machines ; par contre sa syntaxe n’est pas compatible avec le Bourne Shell ;
iii. Le Ksh (commande “ksh”), est le dernier né et le plus complet ; il accepte toutes les commandes du Bourne Shell, possède un historique de commandes perfectionné, et la plupart des fonctionnalités du Csh.
C’est ce dernier qui servira de base pour les exemples qui suivent, bien que beaucoup de remarques soient valables quelque soit le shell utilisé.
I.2. Qu’est ce qu’un processus UNIX ?
Un processus UNIX est un fichier binaire en train de s’exécuter avec un certain environnement :
– des pointeurs sur les fichiers ouverts ;
– des réactions programmées aux signaux :
– division par zéro
– perte de connexion avec la console
– réception du signal INTERRUPT (touche CTRL C)
…
– etc…
Pour démarrer un nouveau processus, c’est à dire chaque fois que l’on veut lancer une nouvelle commande (grep, sort, compile, ..), une technique standard est appliquée ;
• Le processus en cours fait appel à une fonction spéciale qui lui permet de se recopier lui-même intégralement. Tout est recopié exactement en double, la zone mémoire, la zone de code, les pointeurs sur les fichiers, etc… Seul, le code de retour de la fonction permet de différencier l’ori-
ginal (le père) de la copie (le fils) ;
• l’environnement du processus fils est modifié en partie si nécessaire (descripteurs de fichier, variables exportées, signaux,…), puis la zone de code du fils est écrasée avec le code du nouveau programme à exécuter, qui démarre ;
• le père attend la fin du fils, puis continue de s’exécuter.
Cette méthode peut paraître complexe, mais c’est exactement ce qui se passe chaque fois que le shell lance une commande (par la fonction charger_et_lancer() de notre pseudo-interpréteur vu plus haut).
I.3. Format d’une commande UNIX élémentaire
I.3.1. Description
Si l’on oublie pour l’instant les caractères de contrôle du shell comme ‘ ;’ ‘|’ ou ‘&’, et la syntaxe de certaines commandes internes au shell affectation, tests, boucles for,…), une ligne de commande élémentaire a la forme suivante :
<champ0> <champ1> <champ2> … <champN>
les champs étant des suites de caractères terminés par des <espace>, ou des <tabulation>.
Alors :
– le <champ> 0 est supposé être le nom d’un fichier binaire ou ascii, ou le nom d’une commande interne au shell ;
– les <champ> 0 à N sont des paramètres qui seront passés au démarrage à l’exécutable <champ0> (comme un appel de fonction).
Le shell va essayer de transformer chaque ligne de commande de manière à retomber sur ce schéma :
– le premier champ de la ligne prend le rôle de l’exécutable à lancer ;
– tous les arguments (de 0 à N) sont “empilés” lors de l’appel.
Au programme appelé de s’occuper correctement de ses paramètres, en faisant le tri, et en les utilisant de manière souhaitée.
……..
Les entrées-sorties d’une commande UNIX: Guide du KornShell sous UNIX (683 KO) (Cours PDF)