Devoir Hors Présentiel – Numération en Script shell
L'exercice consiste à appliquer différentes opérations à une liste d'entiers. Vous allez écrire plusieurs scripts shell pour effectuer ces opérations, ainsi qu'un script principal. Celui-ci permet de sélectionner l'opération, et d'envoyer la liste d'entiers, donnés en paramètres, au script implémentant l'opération. Pour cela, nous procédons pas à pas.
Testez régulièrement vos avancées en lançant vos scripts avec différentes configurations d'arguments. Vous pouvez même scripter ces différents appels au sein d'un script shell indépendant afin d'automatiser vos tests.
Dans tous les cas, n'oubliez pas d'indiquer l'utilisation de l'interpréteur de commandes bash en écrivant à la première ligne de chaque script : #! /bin/bash et de les rendre exécutables grâce à la commande chmod u+x <mon_script.sh>.
Bon travail !
Readme
Avant d'entamer la partie calculatoire de l'exercice, voici un scénario d'exécution attendu du script num.sh que vous allez implémenter dans les parties suivantes :
$ ./num.sh len 123 4 3 1 $ ./num.sh mir 123 4 56 321 4 65 $ ./num.sh s 123 6 $ ./num.sh Erreur : Argument manquant num.sh applique une opération à chaque nombre d'une liste de nombres entiers positifs donnés en argument. ./num.sh [OP] [ARGS]... OP est l'opération à appliquer, à choisir parmi : * l ou len (pour longueur) : afficher le nombre de chiffres de chaque nombre * m ou mir (pour miroir) : écrire chaque nombre à l'envers (en miroir) * s ou sum (pour somme) : afficher la somme des chiffres de chaque nombre * b ou bin (pour binaire) : écrire chaque nombre, donné sous forme décimale, en binaire * d ou dec (pour décimal) : écrire chaque nombre, donné sous forme binaire, en décimal * i ou int (pour interactif) : commencer la saisie interactive de l'opération à appliquer aux nombres ARGS est la liste des nombres entiers positifs à traiter. $Écrivez un script readme.sh qui affiche ce mode d'emploi.
Récupération des arguments et mise en place du squelette calculatoire
L'objet de cette partie consiste à écrire le script num.sh, qui est en charge de récupérer les arguments qui lui sont passés, puis de lancer l'opération demandée sur ceux-ci s'ils sont conformes.
Dans un premier temps, le script vérifie la conformité des arguments :
- le premier argument doit correspondre à une opération prévue par le mode d'emploi de la commande num.sh (cf. le script readme.sh réalisé à la partie précédente) ;
- tous les arguments suivants doivent être des entiers positifs.
Testez que le nombre d'arguments passés est correct.
Dans une variable op, récupérez la valeur du premier argument.
S'il est indiqué dans sa version longue, utilisez un schéma alternatif pour le normaliser sous la forme de sa lettre unique.
Par exemple, l'opération convertissant un entier binaire en décimal peut être invoquée soit en utilisant le mot dec, soit la lettre d.
Si dec est utilisé, modifiez la valeur de la variable op pour qu'elle soit égale à d.
Après avoir décalé d'un cran la liste des paramètres, stockez dans la variable args l'ensemble des arguments restants.
Vérifiez que les nombres dans args sont des entiers.
Pour ce faire, testez sur chacun d'eux l'évaluation d'une opération arithmétique quelconque.
En cas d'erreur, affichez un message de sortie d'erreur adéquat, lancez le script readme.sh et terminez num.sh.
Pour lancer l'évaluation d'une opération arithmétique, utilisez la commande expr comme suit : isnum="$(expr 0 + "$arg" 2>/dev/null)", avec arg la variable contenant le nombre à tester. Ensuite, testez si la variable isnum est vide. Si c'est le cas, alors expr a échoué : arg n'est pas un nombre entier.
Si la commande expr échoue, elle ne produit rien sur la sortie standard (seulement un message d'erreur sur la sortie standard d'erreur). Ainsi, en récupérant la sortie standard et en vérifiant qu'elle n'est pas vide, on s'assure que les opérandes sont des nombres entiers.Dans le cas contraire, affichez un message de sortie d'erreur adéquat, lancez le script readme.sh et terminez num.sh.
Maintenant que les différents arguments sont corrects et stockés dans des variables indépendantes, il reste à lancer l'opération voulue sur chaque nombre dans args.
Lancer une opération consiste à appeler un script avec un nombre en argument : ce script applique l'opération sur ce nombre.
Implémentez l'aiguillage vers l'appel du script effectuant l'opération, à l'aide d'une structure de contrôle permettant un choix alternatif multiple.
Les scripts seront implémentés dans la partie suivante, et seront nommés comme suit :
- len.sh : afficher le nombre de chiffres (la longueur) de l'entier passé en argument ;
- mirror.sh : écrire à l'envers (en miroir) l'entier passé en argument ;
- sum-digit.sh : afficher la somme des chiffres de l'entier passé en argument ;
- decimal_to_binary.sh : écrire en binaire l'entier positif décimal passé en argument ;
- binary_to_decimal.sh : écrire en décimal l'entier positif binaire passé en argument.
Si la variable op ne correspond à aucune des opérations décrites dans le script readme.sh, affichez un message de sortie d'erreur adéquat, lancez le script readme.sh et terminez num.sh.
Implémentation des différentes opérations
Dans cette partie, vous devez implémenter chaque opération dans un script séparé. Un script ne traite qu'un seul nombre entier positif.
Comme ces sous-scripts seront principalement invoqués depuis le script principal, ne vous souciez pas de vérifier la conformité de l'argument, sauf lorsque demandé autrement (question 3.e). Pour toutes ces opérations, on ignore d'éventuels 0 inutiles au début des nombres. Par exemple, ./num.sh len 042 affiche 2.
Ici, il est possible que l'argument soit invalide : ce peut être un nombre entier positif qui contient des chiffres invalides en binaire, c'est-à-dire différents de 0 et de 1. Prenez ce cas d'erreur en considération : affichez un message de sortie d'erreur adéquat, lancez le script readme.sh et terminez binary_to_decimal.sh.
Une version interactive
Dans cette dernière partie, il s'agit de permettre le choix interactif de l'opération de manière à pouvoir en appliquer plusieurs sur un même ensemble d'entiers positifs. Pour ce faire, l'opération saisie au lancement du script num.sh sera i ou int.
Dans num_interactif.sh, si le mode interactif est demandé, positionnez une variable interactive à "true" (ou toute autre valeur pour signifier l'activation du mode interactif). Demandez ensuite la saisie au clavier de l'opération à appliquer (parmi l, m, s, b ou d).
Encapsulez l'aiguillage de l'opération à appliquer (cf. question 2.g) dans une boucle infinie. La dernière étape de cette boucle consiste à demander la saisie d'une nouvelle opération dans le cas où le mode interactif est activé ; sinon il faut mettre fin à la boucle infinie.