UCL-INGI / LEPL1503-Blog

Blog du projet P3 à l'UCLouvain
MIT License
0 stars 10 forks source link

Fonctions en BASH #19

Closed boucqueymat closed 4 years ago

boucqueymat commented 4 years ago

Bonjour,

Voici ci-après une proposition d'article traitant des fonction en BASH. Je crois qu'à ce stade du projet, elles peuvent s'avérer d'une grande utilité pour executer nos programmes.

Merci de me signaler si des ajouts ou modifications doivent être apportés pour compléter l'article.

Matthieu Boucquey

boucqueymat commented 4 years ago

Functions en BASH

Vous avez sûrement déjà perdu patience à retaper « bêtement » des instructions dans votre terminal. Bien qu’existent des petits raccourcis (EX : fléche du haut) pour récupérer des instructions précédentes, ici est proposé une solution plus générale et modulable : Les fonctions en language BASH. Elles constituent un moyen efficace pour effectuer des commandes groupées qui doivent être répétées.

Le format

Le format d'une fonction en BASH est le suivant :

func(){
     <commands>
}

Les arguments

Il est bien sûr possible de passer des arguments à une fonction. Les arguments de la fonction doivent être fournis directement après le nom de la fonction. Par exemple,

func arg1 arg2

A l'intérieur des fonctions, les arguments sont accessibles par les appels $1, $2, ...

ATTENTION: les arguments ne doivent pas être indiqués dans les paranthèses lors de la définition de la fonction

Boucle FOR

Au sein de ces fonctions, il est possible d'inclure bon nombre de structures d'instructions bien connues. Les boucles FOR, par exemple, suivent la syntaxe suivante :

for var in <list>
do
<commands>
done

Ici, les éléments de la liste sont assignés, les uns après les autres, à la variable var. A chaque itération, les commandes entre do et done sont executées.

L'exemple

Voici un exemple concret lié à la réalisation de notre projet. La fonction timing prenant comme argument le nombre de threads de calcul indique le temps d'execution de l'executable fact pour différents fichiers d'entrée.

timing(){
    make fact
    for i in input1.txt input2.txt input3.txt
    do
    echo Time : $i with $1 threads
    time ./fact -N $1 $i output.txt
    done
    make clean
}

En pratique

Il y a en pratique deux "voies" pour définir des fonctions en BASH.

Dans le terminal

Il est possible de définir directement une fonction dans votre terminal. Neanmoins, ceci implique que votre fonction ne sera pas sauvegardée à long terme.

Dans un fichier .sh

Il est donc préférable de l'insérer dans un fichier .sh, autrement appelé script. Repenant l'exemple ci-dessus, voici le contenu du fichier timing.sh (situé dans le même répertoire que votre Makefile) où la fonction timing est executée 3 fois avec un nombre de threads de calcul croissant.

#!/bin/bash

timing(){
    make fact
    for i in input1.txt input2.txt input3.txt
    do
    echo Time : $i with $1 threads
    time ./fact -N $1 $i output.txt
    done
    make clean
}

timing 1
timing 2
timing 4

Pour exectuer le fichier timing.sh :

./timing.sh

ASTUCE : Il est probable que vous aillez à modifier les permissons (ici, d'execution) du fichier créé. Il suffit d'entrer la commande suivante pour rendre l'execution du fichier .sh accessible:

chmod +x timing.sh

Bien entendu, ceci n'est qu'une introduction aux fonctions en BASH et celle-ci n'attend qu'à être approfondie. Je vous invite vivement à vous documenter pour dénicher peut-être d'autres astuces facilitant encore davantage l'execution de commandes.

Sources:

obonaventure commented 4 years ago

Bon point de départ, je suggère que vous mettiez cela dans une pull request pour qu'on en discute sur GitHub.

Pour le shell, je vous invite à suggérer d'utiliser https://www.shellcheck.net pour valider les scripts développés

Dans la mesure, je vous suggère de d'abord faire tourner fact sans faire de mesure pour que fact se trouve dans la cache du filesystem et éviter que systématiquement la première exécution soit plus lente que les autres

Pour time, il existe aussi http://man7.org/linux/man-pages/man1/time.1.html qui donne un peu plus d'information que le time intégré dans bash