Exercices

1. Exercices de manipulation du shell

Pour rappel, quelques commandes de base dans le shell pour gérer les dossiers et fichiers:

  • ls(1) : affiche la liste des fichiers et dossiers du répertoire spécifié
  • mv(1) : utilitaire pour renommer ou déplacer un fichier ou dossier
  • cp(1) : copie un fichier ou dossier (-r pour les dossiers)
  • rm(1) : efface un fichier ou dossier
  • mkdir(1) : crée un répertoire
  • rmdir(1) : efface un répertoire vide
  • cd(1posix) : change le répertoire courant
  • pwd(1) : affiche le répertoire courant
  • grep(1) : permet de faire des recherches sur le contenu des fichiers

Pour vous familiariser avec le shell, faites les petits exercices suivants dans le shell:

  1. Créez, dans un nouveau répertoire my_dir le fichier nommé first contenant le texte « Inserer ». Vérifiez chaque étape en utilisant une des commandes ls(1), pwd(1) et cat(1).
  2. Copiez le fichier first vers second et ajoutez la ligne « Retirer » à second.
  3. Comment pourriez-vous afficher la taille des fichiers avec ls(1)?
  4. Concaténez first et second dans un nouveau fichier third (sans utiliser la command echo(1))
  5. Utilisez grep(1) pour afficher le numéro de la ligne sur laquelle se trouve le mot « Retirer » dans second.
  6. Retournez dans le répertoire parent de my_dir et copiez le dossier complet my_dir dans my_dir_2.
  7. Effacez le dossier entier my_dir en une seule commande (utilisez rm(1)).

Vous trouverez également sur le cours LSINF1252 sur inginious les exercices suivants :

  1. Utilisation de la commande grep(1) : https://inginious.info.ucl.ac.be/course/LSINF1252/s1_grep
  2. Utilisation des pipes : https://inginious.info.ucl.ac.be/course/LSINF1252/s1_pipes
  3. Utilisation de la commande tar(1) : https://inginious.info.ucl.ac.be/course/LSINF1252/s1_tar
  4. Capture the flag (1): https://inginious.info.ucl.ac.be/course/LSINF1252/s1_ctf1
  5. Capture the flag (2): https://inginious.info.ucl.ac.be/course/LSINF1252/s1_ctf2

2. Découverte du C

Certains côtés du C sont très proches du langage Java que vous connaissez déjà. Ce n’est pas surprenant puisque Java a été conçu avec le langage C comme base. Les inventeurs de Java ont ajouté tout ce qui était nécessaire pour supporter les objets et ont retiré la gestion explicite de la mémoire. Les premiers exercices inginious en C sont très proches de ceux que vous aviez réalisé en Java.

  1. Calcul de la valeur absolue d’une entier: https://inginious.info.ucl.ac.be/course/LSINF1252/absolute_value

  2. Calcul de la factorielle d’un nombre entier: https://inginious.info.ucl.ac.be/course/LSINF1252/factorial

  3. Recherche d’un élément dans un tableau d’entiers: https://inginious.info.ucl.ac.be/course/LSINF1252/tab_find

  4. Compilez et exécutez le code suivant. Expliquez ce que fait l’appel à printf(3).

    int f()
    {
            int a = 1252;
            printf("%d\n", a);
    }
    
    int main(int argc, const char *argv[])
    {
            f();
    }
    
  5. Expliquez à quoi sert l’option -Werror de gcc. Regardez la manpage (gcc(1)).

  6. Recompilez le code du point 4 avec l’option -Werror, que se passe-t-il ? Que faut-t-il rajouter dans le code pour qu’il compile sans erreurs ?

  7. (bonus) comment se fait-il que gcc compilait sans problème au point 4?

  8. Lorsque j’exécute le programme corrigé du point 6 dans une console, j’ai accès à plusieurs variables. L’une d’elles est $? qui permet de récupérer la valeur de retour du dernier programme exécuté. Expliquez à quoi sert cette valeur.

    $ gcc -Werror -std=c99 test.c -o test
    $ ./test
    1252
    $ echo $?
    0
    
  9. Expliquez à quoi sert l’option -Wall de gcc.

  10. Recompilez le code corrigé du point 6 avec les options -Wall et -Werror, que se passe-t-il ? Que faut-il rajouter dans le code pour qu’il compile sans erreurs ?

  11. Ecrivez deux programmes qui réagissent de façon similaire à true(1) et false(1) en utilisant exit(3). Vous pouvez tester le bon fonctionnement de votre programme en exécutant le code suivant dans une console:

    $ if ./true; then echo "true fonctionne"; fi
    true fonctionne
    $ if ! ./false; then echo "false fonctionne"; fi
    false fonctionne
    
    Bash permet aussi de faire des else. Trouvez comment faire en regardant ce lien.

3. Question de bilan final

Le fizz buzz est un programme qui affiche sur la sortie standard pour chaque entier n:

  • fizz buzz si le nombre est divisible par 3 et par 5;
  • fizz si le nombre est divisible par 3;
  • buzz si le nombre est divisible par 5;
  • La valeur de n sinon.

Un étudiant implémente cet algorithme en Bash. Malheureusement, son script comporte plusieurs erreurs. Pouvez-vous identifier et corriger les erreurs en question? Son code est disponible ci-dessous.

#!/bin/bash

x=1
limit=100
if [ ! -z "$1" ]
then
    limit=$1
fi

while [[ $x < "$limit" ]]
do
    if [[0 -eq "($x%3)"  && 0 -eq "($x%5)"]]
    then
        # Check if divide by 3 & 5
        echo "fizz buzz"
    elif [[0 == "($x%5)"]]
    then
        # Check if divide by 5
        echo "buzz"
    elif [[0 == "($x%3)"]]
    then
        # Check if divide by 3
        echo "fizz"
    else
        echo "$x"
    fi
    x=$(( x + 1 ))
done

Il y a 4 différents groupes d’erreurs. Trois d’entre-eux peuvent être facilement repérés via ShellCheck, un outil de vérification statique de code Bash. L’utilisation systématique de ce genre d’outils vous évitera bon nombre d’erreurs fréquentes lors de la rédaction de code.

Verifiez vos réponses