Initiation au terminal - Partie 3
Avec les deux premières parties, vous avez pris une habitude, certes légère, mais nécessaire du terminal et de ses commandes. Continuons cette fois avec l'apprentissage de nouvelles commandes, faisant toujours parties des bases de l'utilisation du terminal.
Reprenons exactement là où nous en étions restés lors de la partie 2, avec la gestion des dossiers et des fichiers.
3.1 Gérer les dossiers et fichiers, suite
Lors de la seconde partie, nous avions appris à créer un fichier, créer un dossier mais aussi les supprimer. Cette fois, nous allons voir comment les déplacer, les renommer et les copier.
Commençons par créer un fichier, sur le bureau, qui nous servira de base de travail, avec les commandes vues précédemment, et dont le maniement ne devrait plus être un secret pour vous :
cd ~/Desktop
mkdir DossierTest
cat > test.txt
Pour déplacer ce fichier, j'utilise la commande mv, avec le chemin souhaité, ici je vais le mettre dans le dossier test créé.
mv test.txt DossierTest/
Pour le remettre à sa place originale, vous pouvez soit :
mv DossierTest/test.txt ./
soit rentrer dans le dossier, puis le déplacer :
cd DossierTest
mv test.txt ../
Attention, cependant avec la seconde solution vous avez bougé de dossier, il faudra peut être revenir dans le dossier du bureau, si nécessaire. N'oubliez pas que pour savoir où vous vous trouvez, vous disposez de la commande :
pwd
Maintenant pour renommer un dossier, c'est extrêmement simple, puisqu'il s'agit de la même commande :
mv test.txt test2.txt
Le fichier est renommé sur votre bureau.
Il s'agit de la même commande, car quand vous déplacez un fichier, vous pouvez lui donner un nouveau nom à son endroit de destination. Vous pouvez donc déplacer et renommer un document en une fois, avec cette commande :
mv test2.txt DossierTest/test.txt
Vous pouvez déplacer et renommer des dossiers de la même manière.
Attention, si un fichier existe à l'emplacement de destination il sera purement et simplement écrasé, sans passer par la case corbeille, veillez donc à vérifier si un fichier existe déjà, avant de lancer la commande.
Voyons maintenant comment copier un fichier, c'est tout aussi simple. Maintenant que notre fichier de test est dans le dossier, je vais en faire une nouvelle copie sur le bureau.
cp DossierTest/test.txt ./test.txt
encore une fois, je peux, au moment de la copie changer le nom du fichier. Cela permet par exemple de dupliquer un fichier au même endroit.
Pour copier un dossier, il faut ajouter un paramètre "R" qui indique la récursion sur la commande.
cp -R DossierTest DossierTest2
A ce moment là du tutoriel, vous devriez avoir 3 fichiers test.txt, un sur votre bureau, et un dans chacun des deux dossiers DossierTest. Bien évidemment le fichier test.txt copié est identique (et n'a pas changé de nom).
3.2 Les commandes en détails
Au fur et à mesure que l'on voit les commandes de base, on peut se demander comment obtenir la liste des paramètres de chacune et comment s'en servir.
La plupart des commandes sont fournies avec un fichier de "man", un manuel en ligne, qui est disponible dans votre terminal. Il existe une commande (et oui !) qui permet de lire ces manuels.
Par exemple, pour voir le fonctionnement et les paramètres de la commande cp, tapons :
man cp
avec le résultat
CP(1) BSD General Commands Manual CP(1)
NAME
cp -- copy files
SYNOPSIS
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
DESCRIPTION
In the first synopsis form, the cp utility copies the contents of the source_file to the target_file. In the second synopsis form, the contents of each named source_file is
copied to the destination target_directory. The names of the files themselves are not changed. If cp detects an attempt to copy a file to itself, the copy will fail.
The following options are available:
-a Same as -pPR options. Preserves structure and attributes of files but not directory structure.
-f If the destination file cannot be opened, remove it and create a new file, without prompting for confirmation regardless of its permissions. (The -f option overrides any
previous -n option.)
The target file is not unlinked before the copy. Thus, any existing access rights will be retained.
vous pouvez le voir, la description, en anglais est vraiment complète et est composée de plusieurs pages.
Si le début de la page vous semble obscure, c'est un peu normal, il faut un peu d'habitude pour les lire facilement.
Ici, la DESCRIPTION du man nous indique que je ne vous ai pas tout dit sur la commande CP, la seconde ligne du SYNOPSYS nous indique que l'on peut copier plusieurs fichiers en simultané, à condition que le dernier élément de la liste, la destination donc, soit un dossier.
Pour sortir du man, tapez simplement la touche Q (quit / quitter) et la molette de votre souris (ou le double-glisser de votre trackpad) permet de faire défiler le contenu, ce n'est pas parce que l'on est dans un terminal que l'on ne peut pas utiliser les dernières technologies.
En faisant défiler le contenu de l'aide, vous allez tomber sur le paramètre -R vu précédemment avec tout le détail s'y rapportant.
En tant que débutant du terminal ce man est un outil indispensable, à utiliser sans modération.
Parfois certains outils propose avec un paramètre d'accéder à une aide simplifiée, soit parce qu'ils n'ont pas de fichier de man, soit parce qu'il est parfois plus rapide d'avoir un aperçu rapide que d'entrer dans man.
Par exemple, si vous tapez la commande cp, sans fichier source et destination, la commande vous renverra une aide rapide.
cp
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
Et si vous avez toujours la possibilité d'aller visiter le man pour plus de détails.
Maintenant prenons la commande php, qui permet d'exécuter des scripts.
Pour obtenir son aide il faut taper
php -h
ou
php --help
Comme vous pouvez le voir cela peut changer selon les commandes, mais globalement, cela tourne toujours autour des mêmes possibilités.
Enfin, si vous aviez installé brew en suivant l'un de nos tutoriels, je vous invite à taper les commandes :
man brew
puis
brew
dans lequel vous pouvez voir que vous pouvez aussi obtenir l'aide en tapant
brew help
mais la commande va plus loin puisque vous pouvez demande l'aider spécifique à une action, par exemple pour install
brew help install
3.3 Multiplier les commandes
Parfois, il peut être pratique de lancer plusieurs commandes en une fois, notamment lorsqu'elles sont longues à s'exécuter, il suffit de les chaîner en les séparant par un point-virgule.
Par exemple, si je veux supprimer tous les fichiers en une seule ligne de commande :
rm test.txt; rm DossierTest/test.txt; rm DossierTest2/test.txt
Les commandes sont exécutées les unes après les autres, chacune attendant que la précédente se termine. Vu la complexité de la commande, cela doit s’exécuter instantanément sur votre Mac, et il n'est pas vraiment possible de vérifier l'enchainement des suppressions.
Mais il peut être aussi pratique d'exécuter des commandes simultanément, notamment avec la multiplication des processeurs et des coeurs dans nos machines. Pour cela, il faut séparer les commandes par un "et commercial" ou "ampersand" :
rmdir DossierTest & rmdir DossierTest2 &
Encore une fois, les commandes sont tellement rapides qu'il est difficile de voir la simultanéité des deux actions.
Pour être plus précis, le & permet d'envoyer une commande en fond de tâche, elle sera ensuite gérée par le gestionnaire de processus, cela peut ainsi fonctionner pour une seule commande. L'avantage est que vous récupérez le prompt pour continuer à faire d'autres choses pendant que la tâche s'exécute.
Les commandes étant exécutées en simultanée, il ne faut donc pas lancer une seconde commande qui nécessite que la première soit terminée pour fonctionner.
Si vous le voulez bien, voyons deux cas concrets d'utilisation de la sérialisation et de la parallélisation des commandes.
Cas n°1
Imaginons un dossier DossierA, assez lourd, que vous souhaitez copier à un autre emplacement DossierA2 pour en faire une sauvegarde, puis vous souhaitez supprimer un fichier FichierB de la sauvegarde.
si vous lancez
cp -R DossierA DossierA2 & rm DossierA2/FichierB
Votre mac va commencer à copier le dossier à son nouvel emplacement, et instantanément supprimer le fichier de la sauvegarde. Or le dossier est lourd, et donc la copie longue, le fichier n'y sera donc pas. Cela ne fonctionne donc pas. Il est donc préférable de sérialiser la commande afin qu'elle s'exécute l'une après l'autre pour être sûr du résultat.
cp -R Dossier1 DossierA2; rm DossierA2/FichierB
Mais le résultat pourrait être pire ! C'est pour cela qu'il faut faire très attention dès qu'on utilise une commande de suppression, voir une commande en général. En effet, changeons un tout petit peu notre postulat de départ, en supprimant le fichier du dossier original, au lieu de la sauvegarde. Si je tape :
cp -R DossierA DossierA2 & rm DossierA/FichierB
Que se passe t il ?
J'espère que vous l'avez deviné par vous même !
Le fichier FichierB sera supprimé avant même d'être copié à sa destination de sauvegarde. Le fichier n'existe donc plus ni dans le dossier original, ni dans la copie, il est définitivement perdu.
Cas n°2
Le second cas est encore plus concret, puisqu'il s'agit de mon utilisation du terminal, dès que j'écris un article. Si vous suivez le site, je vous ai parlé de la commande guetzli qui permet de compresser fortement les fichiers JPEG avec une perte de qualité toute somme minime. Et bien, je n'ai pas fait que vous en parlé, puisque je m'en sers à chaque article pour compresser les images.
Imaginez un dossier Sources, dans lequel il y a une dizaine d'images nommées img1, img2, img3, ....
et un dossier Exports vide.
Le but de la manoeuvre est de compresser toutes les images de Sources dans Exports, en multipliant la commande.
Ainsi, si je lance :
guetzli Sources/img1 Exports/img1; guetzli Sources/img2 Exports/img2; guetzli Sources/img3 Exports/img3; ...
comme vu dans l'article dédié, la commande guetzli est assez longue, et enchaîner une dizaine, douzaine ou centaine de commandes, peut alors prendre un temps infini, d'autant que la commande n'utilise qu'un seul coeur d'un processeur à la fois. Le principal est que cela fonctionnera, mais ce sera vraiment très long, puisque chaque commande attendra que la précédente soit terminée pour se lancer.
Vous commencez à voir l'intérêt de la parallélisation des commandes ?
Et oui, chaque commande étant indépendante, et ne dépendant pas d'une autre, il est possible de les lancer en simultané :
guetzli Sources/img1 Exports/img1 & guetzli Sources/img2 Exports/img2 & guetzli Sources/img3 Exports/img3 & ...
Automatiquement le gestionnaire de processus, va placer une commande par coeur de processeur, afin d'utiliser le maximum de ressource et réduire le temps de calcul. Si il y a plus d'images (et donc de commandes) que de processeurs, elles finiront par se partager les ressources de calcul. A ce moment là, il sera peut être envisageable de limiter le nombre de commandes simultanées, voir de faire un petit script qui permet de les lancer les unes à la suite des autres dès qu'une en cours se termine.
Voici un petit graphique de l'activité de mon Mac lors de l'utilisation de la commande.
Comme vous pouvez le voir, chaque commande utilise 100% d'un coeur, la parallélisation est effective.