Ligne de commande : niveau intermédiaire

De Ensiwiki
Aller à : navigation, rechercher

Les fichiers

~

Dans un système UNIX, on ne peut rien faire si on n'est pas un utilisateur. Vous indiquez au système quel utilisateur vous êtes lorsque vous vous logguez en début de session (sur un TX ou via d'autres moyens). De plus "chaque" utilisateur possède un home, ou homedir, c'est-à-dire un dossier "rien qu'à lui". C'est ce dossier qui est établi comme dossier courant quand vous ouvrez un TX. C'est lui qui contient absolument toutes vos préférences : de vos favoris Internet à vos mots de passe, en passant par les icônes de votre menu, la couleur de votre fond d'écran, et bien sûr, vos documents personnels.

Le tilde est tout simplement un alias vers ce dossier :

 bash-3.2$ ls ~/.ssh/
 bash-3.2$ ls ~/*.txt

On peut aussi faire référence au homedir d'un autre utilisateur en spécifiant son nom après le tilde :

 bash-3.2$ ls ~root/
 bash-3.2$ ls ~username/*.txt

Notion de propriété d'un fichier : chown

En fait, la notion de propriété d'un fichier ne s'applique pas qu'a votre homedir. Chaque fichier d'un système UNIX appartient à un utilisateur

Droits des utilisateurs sur les fichiers : chmod

Un fichier appartient a un utilisateur, mais ce n'est pas pour autant que les autres utilisateurs ne peuvent pas y avoir accès. En fait, c'est au propriétaire de décider qui peut lire, écrire ou exécuter chacun de ses fichiers. Et cela ce fait avec la commande chmod. La syntaxe est la suivante :

 chmod a_qui+quel_droit nom_du_ou_des_fichiers # pour ajouter un droit
 chmod a_qui-quel_droit nom_du_ou_des_fichiers # pour retirer un droit

a_qui indique à qui vous voulez ajouter ou retirer une autorisation. Par contre, on ne peut pas spécifier n'importe quel utilisateur. On est limité aux 3 valeurs suivantes :

  • u : pour user. C'est vous ! En effet, si vous voulez éviter de faire des bêtises, vous pouvez par exemple vous interdire l'écriture d'un de vos fichiers.
  • g : pour group. C'est les utilisateurs de votre groupe, sauf vous.
Spécifique EnsimagÀ l'ENSIMAG, votre groupe c'est votre promotion (ensi1a, tele3a).


  • o : pour others. Tout le reste... Si vous avez un accès other c'est soit que vous êtes vraiment "open", soit que vous avez un problème de sécurité.
Remarque pour utilisateur avancéEn fait, u g et o ne sont pas par rapport à "moi", mais au propriétaire du fichier. A l'Ensimag, on manipule en général des fichiers qui nous appartiennent, mais la distinction est importante !


Maintenant les droits que l'on peut accorder sont :

  • r : reading. C'est le droit en lecture sur un fichier, ou le droit de lister un répertoire.
  • w : writing. C'est le droit en écriture.
  • x : eXecute. C'est le droit de lancer le fichier comme s'il s'agit d'un programme, d'un script... Notez que pour les dossiers, x signifie "le droit de faire quelque chose dans le dossier".
Remarque pour utilisateur avancéUn dossier sans le flag x n'est pas accessible du tout. Un dossier avec le flag x mais sans le flag r est accessible, mais sans possibilité de lister le contenu du répertoire. En pratique, seules les personnes connaissant les noms des fichiers du répertoire peuvent donc accéder à son contenu.


Comme on veut souvent faire plus d'un chmod à la fois, on peut grouper les commandes

 chmod ugo+r go-wx zoubi.txt
Remarque pour utilisateur avancéIl faut savoir qu'il existe un autre type de droit : le flag s. Pensez y le jour où vous ne comprenez pas la différence entre 2 programmes rigoureusement identiques. Si possible avant de vous être arrachés la moité des cheveux. man chmod vous en dira plus.


Pour obtenir la liste des droits sur un fichier (son mode), on peut utiliser ls -l :

 $ ls -l fich
 rwxr-x--- 34 dussejc ensi1a fich

On lit d'abord u, puis g, et enfin o : rwx pour u, rx pour g, rien pour o.

Remarque pour utilisateur avancéOn trouve aussi une autre manière de spécifier un mode, en octal : on code r par 4, w par 2 et x par 1. Le mode est écrit dans le sens u,g,o. Par exemple, le mode du fichier ci-dessus est 750.


Remarque pour utilisateur avancéSi vous voulez des droits plus fins, reseignez vous sur les ACL


Précautions de sécurité !

Si vous laissez votre home accessible en écriture à d'autres utilisateurs, ils peuvent faire ce qu'il veulent de TOUTES les données vous concernant. C'est complètement suicidaire !

Si vous laissez votre home accessible en lecture à d'autres utilisateurs, c'est suicidaire aussi, mais pas pour la même raison : les profs l'interdisent rigoureusement car les gens sont trop tentés d'aller piquer les TPs aux voisins. Si un de vos TPs se fait pomper, vous en serez tenu responsable : un ingénieur doit être capable de faire attention à la sécurité de ses données. Rappelez vous que sur un gros projet, un zéro implique quasiment un redoublement...

L'état par défaut (interdit en lecture et écriture, sauf pour le propriétaire) est donc celui qu'il faut conserver absolument !!! Pour envoyer un fichier à un ami, utilisez le mail, SCP, FTP... mais ne donnez jamais accès à votre home.

Si vraiment, et j'insiste sur le vraiment, vous savez ce que vous faites, alors sachez qu'on peut faire des trucs assez sympathiques en utilisant le droit x des répertoires.

touch

La commande ***touch nom_de_fichier*** a deux fonctions :

  • si le fichier n'existe pas, un fichier vide est créé
  • si le fichier existait déjà, sa date de modification est actualisée comme si vous veniez de le modifier. Mais le fichier n'est pas modifié. C'est souvent utile quand un make échoue.

find

find nom_de_dossier fonctionne un peu comme un ls récursif. Le gros avantage c'est que le format de sortie est très standard, et convient tout à fait à l'exécution de Scripts shell. L'utilisation la plus classique est de le faire suivre d'un grep (voir plus bas).

Mécanique des flux

Pour qu'un utilisateur puisse communiquer avec un programme en ligne de commande, on a déjà vu l'utilisation d'arguments (comme les option ou les noms de fichiers qui suivent le nom de la commande). On constate vite que cette méthode n'est pas interactive : on ne peut faire passer des paramètres qu'au lancement du programme. Or dans beaucoup de cas, on aimerait un peu d'interactivité (ex: "Ceci détruira toutes vos données. Êtes vous sûr? (oui, non, joker)" ). Tout cela se fait via des flux. Quand on lance programme, trois canaux de communication avec l'extérieur sont crées pour relier votre console à ce programme : un pour que l'utilisateur puisse envoyer du texte au programme, et 2 pour que le programme puisse envoyer du texte à l'utilisateur.

  • stdin : Flux d'entrée standard. C'est le flux utilisateur -> programme ;
  • stdout : Flux de sortie standard. C'est le flux normal programme -> utilisateur ;
  • stderr : Flux d'erreur. C'est aussi un flux programme -> utilisateur, mais réservé aux message d'erreurs, ou d'information avancé, inutiles au fonctionnement du programme.

Par exemple, quand vous utilisez la commande whoami, stdin et stderr ne sont pas utilisés, par contre stdout l'est : c'est via ce flux que le programme vous affiche votre nom d'utilisateur.

Remarque pour utilisateur avancéQuestion piège : quel est le premier programme interactif que vous avez lancé aujourd'hui ? C'est votre shell !!! En effet, la commande bash n'est ni plus ni moins qu'un programme qui tourne en boucle, qui analyse le flux d'entrée et qui lance les programmes correspondants au texte que vous avez entré.


Rediriger les flux vers des fichiers : ">" et "<"

Souvent, vous aurez à "enregistrer" le flux de sortie dans un fichier, pour l'envoyer à quelqu'un, le relire plus tard, ou simplement parce qu'il ne "rentre" pas dans la mémoire du shell. Pour cela, il suffit d'ajouter à la fin de la commande >mon_resultat.

 bash-3.2$ whoami >mon_nom
 bash-3.2$ cat mon_nom
 sacquetf
 bash-3.2$

Vous pouvez constater que si on redirige le flux vers un fichier, on n'a plus l'affichage.

Parfois c'est dans l'autre sens : on aimerait envoyer un fichier en entrée du programme (par exemple pour éviter de devoir retaper 42 fois la même chose). C'est pas beaucoup plus compliqué :

 bash-3.2$ pere_noel <ma_liste_de_cadeaux

Certains programmes marchent ainsi de 2 façons, soit on spécifie un fichier en argument, soit on redirige le flux d'entrée. Par exemple :

 bash-3.2$ tail <mon_fichier

équivaut à

 bash-3.2$ tail mon_fichier


Il est également possible de rediriger les flux d'erreur (les erreurs d'exécution d'un programme, les erreurs de compilation lors de l'exécution d'un Makefile, ...), en utilisant 2> au lieu de > :

 bash-3.2$ make 2>mon_log_d_erreurs

Rediriger les flux vers un autre programme : le pipe "|"

Il arrive souvent qu'on veuille envoyer le flux de sortie d'un programme sur le flux d'entree d'un autre programme. Bien sur on peut le faire avec

bash-3.2$ command1 <entree      >temporaire1
bash-3.2$ command2 <temporaire1 >temporaire2
bash-3.2$ command3 <temporaire2 >temporaire3
bash-3.2$ command4 <temporaire3 >sortie

C'est parfois pratique pour debugger, car on garde une trace de tous les flux. Mais quand on est sur de soi, on aimerait le faire plus vite. C'est possible avec le pipe :

bash-3.2$ command1 <entree | command2 | command3 | command4 >sortie

Le flux est traite ligne par ligne, c'est a dire que la comande2 recoit des donnes quand la commande1 envoie un retour a la ligne.

Les pipes "classiques"

 find | grep
 find | xargs

Cœur grisé par le flux de la brosse

grep

sed

awk

Bash fait des choses dans votre dos

&

Maintenant que vous êtes convaincus que bash permet de faire plein de trucs, nous allons voir qu'en plus, on peut les faire en même temps.Voici donc un petit exemple.

Vous avez trouvé une commande qui vous évite d'oublier vos pizzas dans le micro-ondes :

 sleep 10; echo "La pizza est cuite."

Simplement, quand vous lancez votre commande, le terminal se gèle. Il n'effectue plus rien de ce que vous tapez tant que la pizza n'est pas cuite. Par contre, dès que le temps est écoulé, toute les commandes qui ont été rentrées pendant le temps de cuisson vont être interprétées.

L'idéal serait que bash exécute notre commande dans son coin : c'est possible et c'est très simple !

 (sleep 10; echo "La pizza est cuite.") &

Ne vous focalisez pas sur les parenthèses.. L'opérateur qui lance une tache en arrière-plan est &. De façon générale la syntaxe :

 commande options arguments &

va lancer la commande en fond. Vous n'avez donc plus accès au flux d'entrée de votre commande, par contre les flux de sortie et d'erreur restent attachés à votre terminal. Vous aurez deviné que les parenthèses de l'exemple précédent servent juste à appliquer le & aux deux commandes (surtout au sleep d'ailleurs). Sans les parenthèses, seul le echo s'effectue en fond.


Vous avez peut-être aussi constaté qu'au lancement d'une commande en fond, bash vous affiche des nombres bizarres

 bash-3.2$ (sleep 5; echo "La pizza est cuite.") &
 [1] 8158
 bash-3.2$ je_continue_a_travailler_ici

Si vous essayez de lancer plusieurs tâches en fond, vous comprendrez vite que le numéro entre crochets est le numéro de la tâche. Le second est son PID ou Process ID ou IDentificateur de Processus. Ce qu'il faut retenir, c'est que le numéro est propre à un terminal, tandis que le PID est donné par la machine. Si vous avez 2 shells ouverts, et que vous voulez, à partir de l'un, modifier un processus qui à été crée dans l'autre, c'est donc seulement possible avec le PID.

Vous verrez aussi un message une fois que la tâche est terminée :

 [1]+  Done                    ( sleep 5; echo "pizza" )

Celui çi indique que la tâche parallèle s'est terminé correctement.

Qu'advient-il des flux

Les flux de sortie et d'erreur d'un programme lancé en fond sont bien redirigés vers votre terminal. Par contre, ce n'est pas le cas du flux d'entrée. Quand on lance un programme qui attend une entrée, il va donc se stopper. Par exemple :

 bash-3.2$ grep 'test' &
 [1] 20367
 
 [1]+  Stopped                 grep 'test'

En effet, si un programme attend une entrée, bash estime avec raison que ce n'est pas la peine de continuer à l'exécuter, puisque le flux d'entrée du programme est déconnecté. Il nous indique donc qu'il a stoppé le processus. Attention, il l'a stoppé, mis en pause, mais il ne l'a pas fait disparaitre pour autant.

jobs

fg et bg

Lorsqu'un processus est stoppé (il a reçu un signal SIGSTP, par l'intermédiaire par exemple, du raccourci Ctrl-Z), ce processus est mis en pause. Pour reprendre l’exécution du processus, il existe deux commandes : fg et bg. fg permet de reprendre l’exécution dans le terminal. bg lui, fait reprendre l’exécution en arrière plan, comme si le programme avait été lancé avec & (en utilisant bash).

nohup et screen