750 likes | 889 Views
Unix pour l'utilisateur. Les commandes fondamentales. Vérifier la connexion PC/Unix. ping : commande permettant de vérifier qu'une machine est accessible sur le réseau ping adresse_ip ping nom_de machine (nécessite un DNS ou un fichier hosts) Ouverture d'une session interactive
E N D
Unix pour l'utilisateur Les commandes fondamentales
Vérifier la connexion PC/Unix • ping : commande permettant de vérifier qu'une machine est accessible sur le réseau • ping adresse_ip • ping nom_de machine (nécessite un DNS ou un fichier hosts) • Ouverture d'une session interactive • La commande telnet • rlogin
arborescence • / : Répertoire racine, tous les autres répertoires en dépendent. • /bin : Contient les binaires fondamentaux à la gestion de Linux. • /dev : Contient une multitudes de fichiers dits spéciaux. L'un deux correspond à mon modem. Je dois indiquer ce fichier dans la configuration de mes outils de communication. De même /dev/hda1 correspond à la première partition de mon disque dur IDE, si mon disque dur est un SCSI, son nom sera /dev/sda1. Un dernier exemple : /dev/fd0 correspond à mon lecteur de disquettes. • /etc : Contient tous les fichiers de configuration de linux. On y retrouve par exemple le fichier /etc/passwd, qui définit les mots de passe des utilisateurs. • /sbin : Contient les binaires du système. On y trouve par exemple la commande shutdown qui permet d'arrêter l'ordinateur. • /home : Répertoire qui contient les répertoires des utilisateurs du système. Le répertoire des utilisateurs est automatiquement créé avec la création d'un compte. Tous mes fichiers personnels sont dans /home/(maltesse).
Arborescence suite • /lost+found : Répertoire des fichiers perdus. Ces fameux fichiers qui, du fait d'erreur disque, se retrouvent sans chemin d'accès. Le binaire fsck, qui est lancé régulièrement au démarrage de linux, se charge de les détecter et de les stocker dans le répertoire /lost+found • /tmp : Répertoire accessible par tous les utilisateurs du système, il permet de ne pas encombrer son répertoire personnel par des fichiers que l'on souhaite de toute manière détruire ou modifier. • /var/spool : Répertoire des fichiers qui servent de file d'attente. Par exemple, les files d'attente de l'imprimante se trouvent sous ce répertoire. Les données à imprimer, envoyer, ... sont stockées dans ces files d'attentes jusqu'à ce qu'elles soient traitées. • /usr : Contient tout ce qui concerne les binaires utiles à tous les utilisateurs et quelques commandes d'administration. On y trouve cependant d'autres choses: /usr/bin contient donc les binaires disponibles pour les utilisateurs et les scripts. • /usr/X11R6 : Contient tout ce qui concerne Xfree86 (les bibliothèques, les binaires, la documentation). • /usr/include : contient tous les "headers" nécessaires à la programmation dans les différents langages. • /usr/lib : Contient toutes les bibliothèques nécessaires au fonctionnement des logiciels. (comme par exemple la bibliothèque C ou C++ ou tcl/tk). • /usr/local : On y met ce que l'on veut, mais surtout les fichiers d'usage local.
Manipulation des fichiers • Lister les fichiers : ls • Créer un fichier vide : touch nom_fichier • Créer un fichier en saisissant le contenu directement sur la console • cat >nom_fichierVoici mon premier fichier<ctrl-d>
Manipulation des fichiers • Copier de fichiers : cp • Afficher le contenu d'un fichier : cat • Détruire un fichier : rm • Créer un répertoire : mkdir • Changer de répertoire : cd • Copier un fichier d'un répertoire à l'autre • Afficher page à page : more • Désigner plusieurs fichiers dans la même commande • Les caractères joker • Eviter les manipulations hasardeuses* : -i • Détruire un répertoire
Créer des alias de commande • Pour émuler des commandes déjà connues • alias copy=cp • Pour positionner des options par défaut • alias rm='rm -i' • Supprimer un alias défini • unalias rm • Désactivation temporaire • \rm nom_fichier
Détails sur les commandes • man : l'indispensable manuel en ligne Unix • Ou commande –h • Ou commande –help • Ou commande --help
Décryptage d'une page man [bastide@moe bastide]$ man man NAME man - format and display the on-line manual pages manpath - determine user's search path for man pages SYNOPSIS man [-adfhkKtwW] [-m system] [-p string] [-C config_file] [-M path] [-P pager] [-S section_list] [section] name ... Le synopsis montre : - Des options facultatives sans paramètres complémentaires : [-adfhkKtwW] - Des options facultatives qui nécessitent un paramètre complémentaire : [-P pager] - Des paramètres optionnels : [section] - Un paramètre obligatoire : name - Le fait que le paramètre obligatoire peut être répété une ou plusieurs fois : name ...
Retour sur les commandes • Options avancées de cp • copie récursive (-r) • Options avancées de ls • listing long (-l) • listing des fichiers cachés (-a) • listing récursif (-R) • listing avec caractère distinctif (-F) • sans inspections des répertoires (-d) • Options avancées de rm • Destruction récursive (-r) • Destruction forcée (-f)
Redirection des Entrées/Sorties • Chacune de E/S d'un programme peut être redirigée séparément vers un fichier • lire les données d'entrée dans un fichier • Envoyer les résultats ou les erreurs dans un fichier
Caractères de redirection • Redirection de l'entrée standard • wc < .cshrc • Redirection de la sortie standard • ls > liste
Tubes et filtres • La sortie standard d'un programme peut être connectée à l'entrée standard d'un autre • Les résultats du premier programme servent de données au deuxième programme • Tube (pipe) : suite de commandes réliées par le caractère '|' • ls /etc | more • Ls –la | grep lapayre
Différents types de fichiers • Unix connaît plusieurs types de fichiers. Ces différents types sont visibles par l'option -l de la commande ls • Fichier ordinaire (-)Contient n'importe quel type de données. Dans certains cas, la commande file permet de connaître les données contenues dans ce fichier. • Répertoire (d)Contient d'autres fichiers et sous-répertoires. • Lien symbolique (l)Permet de désigner le même fichier par plusieurs noms différents • Fichier spécial : périphérique en mode caractère (c)Dans le répertoire /dev • Fichier spécial : périphérique en mode bloc (b) • Tube nommé (named pipe) (p)Utilisation avancée, pour la communication entre processus • Socket (s)Idem.
Trois catégories d'utilisateurs • Pour chaque fichier, il existe trois type d'utilisateurs : • Le propriétaire (owner) du fichier. La personne qui crée un fichier en est propriétaire, jusqu'à ce qu'elle (ou l'administrateur système) utilise la commande chown. • Les membres du groupe du propriétaire du fichier. • Les autres utilisateurs du système
Trois types d'autorisation • Autorisation d'écriture : permet de modifier un fichier, ou de le supprimer. Pour un répertoire, permet de créer des fichiers dans un répertoire ou de les détruire, et de détruire le répertoire lui-même. • Autorisation de lecture : permet d'afficher le contenu d'un fichier et de le copier. Pour un répertoire, permet de lister les fichiers contenus dans ce répertoire. • Autorisation d'exécution : permet d'exécuter un fichier (il doit s'agir d'un programme compilé ou d'un script). Pour un répertoire, permet de se positionner (cd) dans ce répertoire ou de le traverser (par cd ou ls).
Affichage des autorisations • Affichage en mode symbolique • Désignation en mode octal 1 1 1 1 1 0 1 0 1
La commande chmod • chmod [-Rcfv] mode file ... • Mode symboliques • u,g,o,a : user, group, others, all • +,-,= : ajoute, supprime ou fixe le droit • r,w,x : read, write, execute • Mode octal • Chmod – R 777 ~lapayre/tpUnix donne les droits lecture, écriture exécution pour tous sur le répertoire tpUnix (et ses sous-répertoires)
Commandes de gestion des processus • Lancement d'un processus en tâche de fond • nomProcessus & • Si oubli : processus déjà lancé, Ctrl Z puis bg • Affichage des processus en cours : ps -ef • Tuer un processus : kill -9 background
Par nom: find . -name "*html" -print Par possesseur: find . -user igsi -print Par groupe: find . -group igsi -print Par type: find . -type d -name "*html" –print Par date d’accès find . –amin –3 –print Par permissions find . –perm 777 -print Affichage du nom des fichiers trouvés: -print Exécution d'une commande sur les fichiers trouvés: -exec commande {} \; find . -name "*.bak" -exec rm {} \; find . -name "*.bak" -ok rm {} \; La commande find : tests Rechercher des fichiers, exécuter des commandes sur les fichiers
Un peu de C # include <stdio.h> main () { printf("hello world \n"); } • Compilation avec gcc • gcc –o hello hello.c • gcc rend le fichier hello exécutable
Éditeur Kate • kate & cc –o forki.c forki source exécutable
un peu de C • Par convention tous les programmes C possèdent une fonction appelée main. C'est cette fonction qui sera lancée à l'exécution du programme. Les parenthèses vides () indiquent que main n'utilise pas de paramètre. • # include <stdio.h> est interpreté par le préprocesseur C. • stdio.h est un fichier définissant certaines macro-instructions et certaines variables utilisées par la bibliothèque des E/S . • Le texte de main est compris entre 2 accolades { et } ; elles délimitent la fonction( begin end du Pascal ). • \n correspond au caractère new-line et provoque le passage à la ligne
un peu de C • 1. Les types de données char caractère int entier float réel simple précision double réel double précision • 22. la sortie avec format : printf printf ( " libellé + format ",arg1,arg2,...) chaque format est introduit par %, les différents formats sont : d: decimal o: octal x: hexadecimal u: decimal non signé c: un seul caractère s: une chaîne de caractères e: de la forme - m.nnnnnn E xx type float ou double f: de la forme - mmm.nnnnnn type float ou double g: n'impr. pas les zéros non signifi.type float ou double • 2. Les entrées-sorties • 21. l'entrée et la sortie standard : getchar et putchar getchar() : permet de lire un caractère à la fois depuis le terminal. La fin de fichier ( ^D ou Del sur le terminal ) putchar(x): envoie le caractère x sur le terminal. On peut changer la destination standard en utilisant la réorientation de UNIX.
un peu de C • 23. l'entrée avec format : scanf scanf ( " libellé + format ", arg1, arg2,.....) format en entrée : d: entier décimal o: entier en octal x: entier en hexa h: entier de type short c: un seul caractère s: une chaine de caractères f: un nombre en virgule flottante exemple : float a; int b; char baratin [ 10 ] ; scanf ("%f %d %s",&a,&b,baratin );
Construire la commande WC en langage c • La commande wc existe (testez la) • Il s'agit de la reprogrammer, vous appellerez cette commande wclin • Vous utiliserez notamment : • getchar() : permet de lire un caractère à la fois depuis le terminal • If avec expression dans laquelle &&(et), ||(ou) • nb++ (permet d’incrémenter un entier nb) • '\n' est le caractère de fin de ligne • -1 (en fait EOF) correspond à la fin de fichier • printf pour afficher les résultats
Construire la commande WC en langage c #include <stdio.h> main() { int nbl=0; int nbm=0; int nbc=0; int caract; int oldcaract; while ((caract=getchar())!=-1) { nbc++; if (caract=='\n') nbl++; if (nbc!=1 && ((caract=='\n' && (oldcaract!='\n' && oldcaract!=' ')) || (caract==' ' && (oldcaract!='\n' && oldcaract!=' ')))) nbm++; oldcaract=caract; } if (oldcaract==-1) --nbm; printf("nb lignes : %d, nb mots : %d, nb caract : %d\n",nbl,nbm,nbc); }
Utiliser la commande WC en langage c • Créez un fichier de quelques lignes. Appliquez wclin à ce fichier sans modifier le fichier, en utilisant les fonctionnalités de UNIX • Redirections ??? Wclin < fichieressai
Construisez la commande WC en langage c avec utilisation d’arguments • Un programme c commence toujours par l’appel de la fonction main. Il est possible de passer des paramètres : • Main(argc,argv) int argc; char *argv[]; • argc est le nombre d’éléments du tableau argv • argv est un pointeur sur le tableau de chaînes de caractères des arguments utilisés par main • Par exemple : • L’appel « wclin1 fichieressai » de la commande wclin1 donne à argc la valeur 2, argv[0] contient le nom wclin1 et argv[1] contient le nom du fichier fichieressai.
Construisez la commande WC en langage c avec utilisation d’arguments • Construisez wclin1 (wclin adaptée pour utiliser les arg?? En lisant dans un fichier) • Vous utiliserez : FILE *fichier; type fichier=fopen(argv[1],"r"); ouverture feof(fichier)) fin de fichier caract = fgetc(fichier) lecture caractère/caractère fclose(fichier); fermeture • Vous utiliserez cette commande sur un fichier quelconque « wclin1 fichieressai »
Construisez la commande WC en langage c avec utilisation d’arguments #include <stdio.h> main(argc,argv) char **argv; int argc; { int nbl=0; int nbm=0; int nbc=0; int caract; int oldcaract; FILE *fichier; /* ouverture du fichier */ printf("%s \n",argv[1]); fichier=fopen(argv[1],"r"); while (!feof(fichier)) { caract=fgetc(fichier); nbc++; if (caract=='\n') nbl++; if (nbc!=1 && ((caract=='\n' && (oldcaract!='\n' && oldcaract!=' ')) || (caract==' ' && (oldcaract!='\n' && oldcaract!=' ')))) nbm++; oldcaract=caract; } fclose(fichier); if (oldcaract==-1) --nbc; printf("nb lignes : %d, nb mots : %d, nb caract : %d\n",nbl,nbm,nbc); }
Time sharing • Lorsque plusieurs processus sont lancés sur un seul processeur, ils se partagent la ressource. • Pour visualiser ce phénomène, réalisez un programme c très simple. Il s’agit de réaliser une boucle de 20 itérations (avec un for) dans laquelle on place une pause de 5 secondes (sleep(5)) et qui affiche un message identifiant le processus avant la pause et un après. Ce programme s’appellera lance, il utilisera la notion d’arguments de commande : • Vous utiliserez « lance proc1 » pour voir les messages de proc1. • Vous lancerez en parallèle un processus proc1 et un proc2 pour voir comment le time-sharing opère.
Time sharing #include <stdio.h> main(argc,argv) char **argv; int argc; { int i; for (i=0;i<20;i++) { printf("avant sleep %d de %s\n",i+1,argv[1]); sleep(5); printf("après sleep %d de %s\n",i+1,argv[1]); } printf("fin de %s\n",argv[1]); }
Communication entre deux processus liés • Un processus peut créer un fils (une duplication complète de lui-même,avec son segment de pile…) par exemple dans une application multimédia, chacun des fils gère un média différent. • L ’instruction Fork( ) crée un tel fils • Les threads sont des processus légers. Ils partagent le segment de pile et une partie du segment de données avec le père. Mais la mise en place est beaucoup moins aisée, nous ne l ’aborderons pas cette année. P3 P1 Son Vidéo P2
Primitives de gestion des processus • Identification d ’un processus • getpid() : n° du processus • getppid() : n° du processus père • à noter, le père d ’un processus est par défaut le shell de lancement. • Identification du propriétaire • getuid() : n° du propriétaire réel • getgid() : n° de groupe réel • Mise en sommeil • sleep(n) : n secondes
Primitive fork() • Cette primitive permet la création dynamique d ’un nouveau processus qui est une copie exacte du processus appelant : il s ’appelle processus fils. • Il hérite de son père : • le même code • une copie de la zone de données • la priorité • les propriétaires • les descripteurs de fichier • … • Dans le programme, on teste la valeur de retour de la fonction fork() pour n ’exécuter que le code correspondant au père ou au fils. • valeur 0 on est dans le fils • valeur -1 il y a une erreur de création • valeur = n 0 on est dans le père, n est le numéro du fils
Exemple de Fork() #include <stdio.h> #include <stdlib.h> #include <unistd.h> main() { int numfils; int status; numfils = fork(); if (numfils == -1) { printf("erreur de cration \n"); exit(1); } if (numfils == 0) { … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ } else { … /* écrire ici le code du programme père */ … wait(status); /* le père attend le fils pour fermer */ } } if (numfils == 0) { … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ } { … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ }
Exemple de Fork() #include <stdio.h> #include <stdlib.h> #include <unistd.h> main() { int numfils; int *status; numfils = fork(); Switch (numfils) { case –1: printf("erreur de cration \n"); exit(1); break; case 0: … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ break; default: … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ } } … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ break; … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ Break;
exit, wait et variable status numfils=fork(); Switch (numfils) { case –1: printf("erreur de création \n"); exit(1); break; case 0: /* écrire ici le code du programme fils */ … exit(numfils);/* permet de renvoyer le num du fils */ /* que VOUS donnez */ break; default: … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ /* affiche le numéro placé dans l'exit*/ printf("le fils %d a quitté \n", (int) status/256); } }
Fork itératif for (i=0 ; i < nbfils ; i++) { val=fork(); if (val==0) { /* un fils */ int n,num; char message[15]; printf("je suis le fils %d de ID %d et de pere %d \n", i,getpid(),getppid()); … blabla … exit(i); } } for (i=0;i<nbfils;i++) { wait(&status); printf("PERE : mon fils %d a fini\n",(int) status/256); }
Communication entre père et fils • Entre un processus père et un fils, il est possible de communiquer par : • Fichier • mémoire partage : shared memory • par sockets : AF_INET ou AF_UNIX, TCP ou UDP • par tubes • les tubes nommés utilisant la primitive open • les tubes anonymes utilisant la primitive pipe • Les tubes anonymes ne sont utilisables qu’entre des processus apparentés.
Les tubes • Les tubes (pipes) permettent le transfert de données entre des processus selon un schéma premier entré / premier sorti (FIFO) • Leur mise en œuvre permet aux processus de communiquer même s ’ils ne connaissent pas les processus qui sont à l ’autre bout du tube. • Nous ne développerons ici que la mise en place des tubes anonymes.
Communication entre père et fils par tubes anonymes lecture Ecriture TUBE • Un tube est unidirectionnel • Pour écrire sur un tube, il faut le fermer en lecture • Pour lire dans un tube, il faut le fermer en écriture • Pour un tube donné, un processus sera ou bien écrivain, ou bien lecteur, mais pas les deux en même temps. • C ’est un mode de fonctionnement totalement asynchrone. Les valeurs sont écrites par un processus, la seule garantie est l ’ordre FIFO pour la lecture.
Fonctionnement des tubes Processus écrivain Processus lecture 1 • Si les processus doivent échanger des données, il faut deux tubes un père/fils et un fils/père 2 1 3 2 1 1 3 2
Exemple de tubes #include <stdio.h> #define lire 0 #define ecrire 1 main() { int no_fils,n; int *status; char c; /* declaration des tubes */ int tubepf[2],tubefp[2]; printf("DEBUT : Je suis le processus PERE %d \n",getpid()); printf("DEBUT : No du grand-pere %d \n",getppid()); /* initialisation des pipes */ pipe(tubefp); pipe(tubepf); if ((no_fils=fork())==-1) { printf("Je suis le PERE impossible de cree le fils \n"); exit (1); } Tube où le père écrit et le fils lit : du Père vers le Fils Tube où le fils écrit et le père lit : du Fils vers le Père