{
  "chapter": {
    "id": "shell-unix",
    "level": "premiere",
    "theme": "Architectures",
    "title": "Shell Unix et commandes",
    "description": "Ligne de commande Unix : navigation dans\nl'arborescence (`ls`, `cd`, `pwd`), manipulation des\nfichiers (`cp`, `mv`, `rm`, `mkdir`), affichage\n(`cat`, `less`), recherche (`grep`, `find`),\nredirections et tubes, droits d'accès.",
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "pwd"
      ],
      "title": "Dossier courant",
      "statement": "Quelle commande affiche le **chemin du dossier courant** ?",
      "options": [
        {
          "text": "`where`",
          "correct": false,
          "feedback": "Aucune commande `where`\nn'existe dans le standard\nUnix pour cet usage.\n"
        },
        {
          "text": "`pwd`",
          "correct": true,
          "feedback": "Bonne réponse : `pwd` (print working\ndirectory) affiche le chemin absolu du\ndossier où l'on se trouve.\n"
        },
        {
          "text": "`cd`",
          "correct": false,
          "feedback": "La commande `cd` permet de\nchanger de dossier, mais\nn'affiche pas le chemin\ncourant.\n"
        },
        {
          "text": "`ls`",
          "correct": false,
          "feedback": "La commande `ls` liste le\ncontenu d'un dossier, mais\nn'affiche pas son chemin\nd'accès.\n"
        }
      ],
      "explanation": "Réflexe utile : `pwd` quand on est perdu\ndans l'arborescence. La plupart des shells\nl'affichent dans l'invite (« prompt »)."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "ls"
      ],
      "title": "Lister",
      "statement": "Quelle commande affiche la **liste des fichiers**\nd'un dossier ?",
      "options": [
        {
          "text": "`dir`",
          "correct": false,
          "feedback": "Existe sur Windows (DOS), parfois sur\nLinux comme alias, mais le standard\nUnix est `ls`.\n"
        },
        {
          "text": "`ls`",
          "correct": true,
          "feedback": "Bonne réponse : `ls` (list) affiche le\ncontenu du dossier courant. Options :\n`-l` (détaillé), `-a` (cachés), `-h`\n(tailles lisibles).\n"
        },
        {
          "text": "`show`",
          "correct": false,
          "feedback": "Cette commande n'est pas\nstandard sur les systèmes\nUnix.\n"
        },
        {
          "text": "`list`",
          "correct": false,
          "feedback": "Cette commande n'est pas\nstandard sur les systèmes\nUnix. La commande\nconsacrée est `ls`.\n"
        }
      ],
      "explanation": "Avec des options : `ls -lh`\ndonne un affichage détaillé,\navec des tailles lisibles.\nPour révéler les fichiers\ncachés (dont le nom commence\npar un point), on utilise\nl'option `-a`. L'idiome\n`ls -la` est l'un des plus\nutiles à connaître."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "cd"
      ],
      "title": "Changer de dossier",
      "statement": "Quelle commande **change** de dossier ?",
      "options": [
        {
          "text": "`open`",
          "correct": false,
          "feedback": "Sur macOS, `open` lance une application,\npas un changement de dossier.\n"
        },
        {
          "text": "`enter`",
          "correct": false,
          "feedback": "Aucune commande `enter`\nstandard n'existe sous\nUnix pour cet usage.\n"
        },
        {
          "text": "`cd`",
          "correct": true,
          "feedback": "Bonne réponse : `cd` (change directory)\nsuivi du chemin. Sans paramètre :\nrevient au dossier personnel\n(`/home/user`). `cd ..` : remonte d'un\nniveau.\n"
        },
        {
          "text": "`go`",
          "correct": false,
          "feedback": "Aucune commande `go`\nstandard ne permet de\nchanger de dossier sous\nUnix.\n"
        }
      ],
      "explanation": "Astuces : `cd -` revient au dossier\nprécédent ; `cd ~` va au dossier\npersonnel ; `cd /` à la racine du système\nde fichiers."
    },
    {
      "id": "q04",
      "difficulty": 1,
      "skills": [
        "mkdir"
      ],
      "title": "Créer un dossier",
      "statement": "Quelle commande **crée un dossier** ?",
      "options": [
        {
          "text": "`md`",
          "correct": false,
          "feedback": "Sur Windows, oui. Sur Unix, c'est\n`mkdir`.\n"
        },
        {
          "text": "`new`",
          "correct": false,
          "feedback": "Aucune commande `new`\nstandard ne crée un\ndossier sous Unix.\n"
        },
        {
          "text": "`createdir`",
          "correct": false,
          "feedback": "Cette commande n'est pas\nstandard sous Unix. La\ncommande consacrée est\n`mkdir`.\n"
        },
        {
          "text": "`mkdir`",
          "correct": true,
          "feedback": "Bonne réponse : `mkdir` (make\ndirectory) suivi du nom du dossier.\nOption `-p` : crée les dossiers\nintermédiaires si nécessaire.\n"
        }
      ],
      "explanation": "Pour créer une arborescence en une fois :\n`mkdir -p projet/src/utils`. Crée tous les\ndossiers nécessaires."
    },
    {
      "id": "q05",
      "difficulty": 1,
      "skills": [
        "cp"
      ],
      "title": "Copier",
      "statement": "Quelle commande **copie** un fichier ?",
      "options": [
        {
          "text": "`copy`",
          "correct": false,
          "feedback": "Existe sur Windows. Sur Unix, c'est\n`cp`.\n"
        },
        {
          "text": "`mv`",
          "correct": false,
          "feedback": "La commande `mv` permet de\n**déplacer** ou de\n**renommer** un fichier,\nmais pas de le copier.\n"
        },
        {
          "text": "`cp`",
          "correct": true,
          "feedback": "Bonne réponse : `cp source destination`.\nPour copier un dossier : `cp -r` (récursif).\n"
        },
        {
          "text": "`duplicate`",
          "correct": false,
          "feedback": "Aucune commande `duplicate`\nstandard n'existe sous\nUnix.\n"
        }
      ],
      "explanation": "Très utilisé : `cp -r dossier1 dossier2`\ncopie tout l'arbre. `cp -i` demande\nconfirmation avant d'écraser."
    },
    {
      "id": "q06",
      "difficulty": 1,
      "skills": [
        "mv"
      ],
      "title": "Déplacer / renommer",
      "statement": "Quelle commande **déplace ou renomme** un\nfichier ?",
      "options": [
        {
          "text": "`rename`",
          "correct": false,
          "feedback": "Existe (par exemple en Perl), mais le\nstandard Unix est `mv`.\n"
        },
        {
          "text": "`move`",
          "correct": false,
          "feedback": "Existe sur Windows. Sur Unix, `mv`.\n"
        },
        {
          "text": "`mv`",
          "correct": true,
          "feedback": "Bonne réponse : `mv source destination`.\nSi la destination est dans le même\ndossier avec un nom différent, c'est\nun renommage.\n"
        },
        {
          "text": "`change`",
          "correct": false,
          "feedback": "Aucune commande `change`\nstandard ne déplace ou ne\nrenomme un fichier sous\nUnix.\n"
        }
      ],
      "explanation": "Renommer : `mv ancien.txt nouveau.txt`.\nDéplacer : `mv fichier.txt /home/alice/`.\nSur les FS, déplacer dans le même volume\nest instantané (juste mise à jour de\nl'inode)."
    },
    {
      "id": "q07",
      "difficulty": 1,
      "skills": [
        "rm"
      ],
      "title": "Supprimer",
      "statement": "Quelle commande **supprime** un fichier ?",
      "options": [
        {
          "text": "`delete`",
          "correct": false,
          "feedback": "Aucune commande `delete`\nstandard ne supprime un\nfichier sous Unix.\n"
        },
        {
          "text": "`rm`",
          "correct": true,
          "feedback": "Bonne réponse : `rm fichier.txt`.\n**Attention** : pas de corbeille en\nligne de commande, suppression\n**définitive**.\n"
        },
        {
          "text": "`erase`",
          "correct": false,
          "feedback": "Aucune commande `erase`\nstandard ne supprime un\nfichier sous Unix.\n"
        },
        {
          "text": "`rmdir`",
          "correct": false,
          "feedback": "Erreur : `rmdir` ne supprime qu'un dossier\n**vide** ; sur un fichier, il répond\n« Not a directory » et ne supprime rien.\n"
        }
      ],
      "explanation": "`rm -r dossier` supprime un dossier (et\ntout son contenu). `rm -rf /` est la\ncommande la plus dangereuse possible :\ndétruit tout le système."
    },
    {
      "id": "q08",
      "difficulty": 1,
      "skills": [
        "cat"
      ],
      "title": "Afficher un fichier",
      "statement": "Quelle commande **affiche le contenu** d'un\nfichier texte ?",
      "options": [
        {
          "text": "`read`",
          "correct": false,
          "feedback": "Existe mais lit l'entrée standard,\npas un fichier.\n"
        },
        {
          "text": "`cat`",
          "correct": true,
          "feedback": "Bonne réponse : `cat fichier.txt`\naffiche tout le contenu d'un coup.\nPour les gros fichiers, préférer\n`less` (page par page).\n"
        },
        {
          "text": "`show`",
          "correct": false,
          "feedback": "Aucune commande `show`\nstandard n'affiche le\ncontenu d'un fichier sous\nUnix.\n"
        },
        {
          "text": "`open`",
          "correct": false,
          "feedback": "Sur macOS, `open` lance l'application\nassociée, pas le shell.\n"
        }
      ],
      "explanation": "`cat` (concatenate) : affiche **et**\nconcatène plusieurs fichiers\n(`cat a.txt b.txt`). Variantes : `head`\n(début), `tail` (fin), `tac` (à l'envers)."
    },
    {
      "id": "q09",
      "difficulty": 1,
      "skills": [
        "chemin"
      ],
      "title": "Chemins",
      "statement": "Que désignent `.` et `..` dans un chemin ?",
      "options": [
        {
          "text": "Des messages d'erreur affichés par le système",
          "correct": false,
          "feedback": "Au contraire, ce sont des\nentrées normales et\nparfaitement valides du\nsystème de fichiers.\n"
        },
        {
          "text": "`.` = dossier courant ; `..` = dossier parent",
          "correct": true,
          "feedback": "Bonne réponse : permettent les chemins\nrelatifs. `./script.sh` exécute le\nscript du dossier courant.\n`../fichier` désigne le fichier dans le\ndossier parent.\n"
        },
        {
          "text": "Des fichiers cachés du système",
          "correct": false,
          "feedback": "Cette interprétation est\nimprécise : les notations\n`.` et `..` ne désignent\npas des fichiers cachés\nau sens classique du\nterme, mais des\nréférences particulières\ndans l'arborescence.\n"
        },
        {
          "text": "Des séparateurs de chemin",
          "correct": false,
          "feedback": "Le caractère qui sépare\nles éléments d'un chemin\nest `/`, et non le point.\n"
        }
      ],
      "explanation": "Tous les dossiers possèdent ces deux\nentrées spéciales (à la racine `/`, les\ndeux désignent la racine elle-même).\n`cd ..` remonte ; `./script.sh` permet\nd'exécuter un script du dossier courant,\ncar ce dossier ne figure pas dans le\nPATH."
    },
    {
      "id": "q10",
      "difficulty": 1,
      "skills": [
        "help"
      ],
      "title": "Aide d'une commande",
      "statement": "Comment **afficher l'aide** d'une commande\nUnix ?",
      "options": [
        {
          "text": "`info commande`",
          "correct": false,
          "feedback": "Existe sur certains systèmes (GNU\ninfo), plus complet que `man` mais\nmoins universel.\n"
        },
        {
          "text": "`commande --aide`",
          "correct": false,
          "feedback": "Existe avec `--help` (en anglais), mais\nce n'est qu'un résumé court.\n"
        },
        {
          "text": "`help commande`",
          "correct": false,
          "feedback": "Existe pour les commandes intégrées au\nshell (Bash), mais le standard est\n`man`.\n"
        },
        {
          "text": "`man commande`",
          "correct": true,
          "feedback": "Bonne réponse : `man` (manual) ouvre\nla page de manuel, par exemple `man ls`.\nNavigation : flèches, `/` pour\nrechercher, `q` pour quitter.\n"
        }
      ],
      "explanation": "`man ls` ou `ls --help` : selon le\ncontexte. Pour rechercher : `man -k mot`.\nApprendre à lire le `man` est essentiel\npour devenir autonome."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "redirection"
      ],
      "title": "Redirection sortie",
      "statement": "Que fait `ls > liste.txt` ?",
      "options": [
        {
          "text": "Elle affiche simplement le contenu actuel de `liste.txt`",
          "correct": false,
          "feedback": "C'est précisément\nl'inverse : on écrit\ndans `liste.txt`, on n'en\nlit pas le contenu.\n"
        },
        {
          "text": "Redirige la sortie de `ls` vers `liste.txt` au lieu de l'afficher",
          "correct": true,
          "feedback": "Bonne réponse : `>` redirige la sortie\nstandard. Pour **ajouter** sans\nécraser : `>>`.\n"
        },
        {
          "text": "Elle compare la sortie de `ls` au contenu de `liste.txt`",
          "correct": false,
          "feedback": "Aucune comparaison n'est\nréalisée. L'opérateur `>`\nsert à rediriger une\nsortie, et non à\ncomparer.\n"
        },
        {
          "text": "Elle renomme la commande `ls` en `liste.txt`",
          "correct": false,
          "feedback": "Aucun renommage n'a lieu.\nLa commande `ls` reste\ninchangée ; seul son\nrésultat est redirigé\nvers le fichier.\n"
        }
      ],
      "explanation": "Redirections : `>` (sortie),\n`>>` (sortie ajoutée), `<` (entrée),\n`2>` (erreur). Ex. : `ls > out.txt\n2> err.txt` sépare sortie et erreurs."
    },
    {
      "id": "q12",
      "difficulty": 2,
      "skills": [
        "pipe"
      ],
      "title": "Pipe",
      "statement": "Que fait le caractère `|` (pipe) en shell ?",
      "options": [
        {
          "text": "Il envoie la sortie d'une commande vers l'entrée de la suivante",
          "correct": true,
          "feedback": "Bonne réponse : `ls | grep .txt`\nfiltre la sortie de `ls` pour ne\ngarder que ce qui contient « .txt ».\nTrès puissant pour combiner des\ncommandes simples.\n"
        },
        {
          "text": "Il répète en boucle la commande placée avant lui",
          "correct": false,
          "feedback": "Aucune notion de boucle\nn'est associée à ce\nsymbole dans\nl'interpréteur de\ncommandes.\n"
        },
        {
          "text": "Il introduit un commentaire ignoré par l'interpréteur",
          "correct": false,
          "feedback": "Le caractère qui introduit\nun commentaire dans\nl'interpréteur de\ncommandes est `#`, et\nnon `|`.\n"
        },
        {
          "text": "Il sépare deux commandes exécutées indépendamment l'une de l'autre",
          "correct": false,
          "feedback": "Erreur : c'est le rôle du\npoint-virgule `;`. Avec `|`, les deux\ncommandes sont liées : la seconde lit\nce que la première écrit.\n"
        }
      ],
      "explanation": "Philosophie Unix : « petites commandes\nqui font une seule chose, combinables\npar pipes ». Exemple :\n`cat fichier.log | grep \"error\" | wc -l`\ncompte les lignes contenant « error »."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "grep"
      ],
      "title": "Recherche dans un fichier",
      "statement": "Quelle commande **cherche un motif** dans un\nou plusieurs fichiers ?",
      "options": [
        {
          "text": "`grep`",
          "correct": true,
          "feedback": "Bonne réponse : `grep motif fichier`.\n`grep -r motif dossier/` (récursif).\n`grep -i` (insensible à la casse).\n"
        },
        {
          "text": "`look`",
          "correct": false,
          "feedback": "Existe mais limité aux fichiers triés.\n"
        },
        {
          "text": "`find`",
          "correct": false,
          "feedback": "Erreur : `find` cherche des **fichiers**\ndans l'arborescence.\n"
        },
        {
          "text": "`search`",
          "correct": false,
          "feedback": "Erreur : pas standard.\n"
        }
      ],
      "explanation": "`grep` (Global Regular Expression Print)\nutilise des **expressions régulières** pour\nrechercher un motif efficacement dans un\nensemble de fichiers."
    },
    {
      "id": "q14",
      "difficulty": 2,
      "skills": [
        "find"
      ],
      "title": "find",
      "statement": "Quelle commande **trouve des fichiers** dans\nl'arborescence selon des critères (nom,\ntaille, date) ?",
      "options": [
        {
          "text": "`find`",
          "correct": true,
          "feedback": "Bonne réponse : `find . -name \"*.txt\"`\ntrouve tous les .txt à partir du\ndossier courant. Très puissant et\nflexible.\n"
        },
        {
          "text": "`locate`",
          "correct": false,
          "feedback": "Existe (utilise une base indexée), mais\nla commande standard est `find`.\n"
        },
        {
          "text": "`grep`",
          "correct": false,
          "feedback": "Erreur : `grep` cherche dans le contenu.\n"
        },
        {
          "text": "`look`",
          "correct": false,
          "feedback": "Erreur : pas pour ça.\n"
        }
      ],
      "explanation": "`find` parcourt récursivement et applique\ndes actions : afficher, supprimer,\nexécuter une commande sur chaque résultat.\nTrès puissant."
    },
    {
      "id": "q15",
      "difficulty": 2,
      "skills": [
        "permission-chmod"
      ],
      "title": "chmod",
      "statement": "Que fait `chmod +x script.sh` ?",
      "options": [
        {
          "text": "Renomme le fichier en ajoutant un suffixe `x` à son nom",
          "correct": false,
          "feedback": "Erreur : le renommage se fait avec `mv`,\net `chmod` ne touche jamais au nom.\n"
        },
        {
          "text": "Ajoute la permission d'exécution au fichier",
          "correct": true,
          "feedback": "Bonne réponse : `chmod` change les\npermissions. `+x` ajoute le bit\nd'exécution. Indispensable pour les\nscripts.\n"
        },
        {
          "text": "Rend le fichier invisible dans les listages de `ls`",
          "correct": false,
          "feedback": "Sous Unix, masquer un\nfichier consiste à\npréfixer son nom par\nun point (par exemple\n`.fichier`). La commande\n`chmod` ne touche pas\nau nom, elle modifie\nles droits d'accès.\n"
        },
        {
          "text": "Supprime le fichier après confirmation",
          "correct": false,
          "feedback": "Erreur : la suppression se fait avec\n`rm` ; `chmod` ne détruit jamais rien.\n"
        }
      ],
      "explanation": "Sans `+x`, on ne peut pas faire\n`./script.sh`. Trois bits par catégorie\n(utilisateur, groupe, autres) : r (lecture),\nw (écriture), x (exécution)."
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "wc"
      ],
      "title": "Compter",
      "statement": "Quelle commande **compte** les lignes, mots et\ncaractères d'un fichier ?",
      "options": [
        {
          "text": "`length`",
          "correct": false,
          "feedback": "Erreur : pas standard.\n"
        },
        {
          "text": "`cnt`",
          "correct": false,
          "feedback": "Erreur : pas standard.\n"
        },
        {
          "text": "`count`",
          "correct": false,
          "feedback": "Erreur : pas standard.\n"
        },
        {
          "text": "`wc`",
          "correct": true,
          "feedback": "Bonne réponse : `wc` (word count).\nOptions : `-l` (lignes), `-w` (mots),\n`-c` (octets), `-m` (caractères).\n"
        }
      ],
      "explanation": "Idiome utile : `cat fichier | wc -l`\n(compter les lignes), ou plus\ndirectement `wc -l fichier`. Très utilisé\ndans des pipelines."
    },
    {
      "id": "q19",
      "difficulty": 2,
      "skills": [
        "chemins-absolu-relatif"
      ],
      "title": "Chemin absolu vs relatif",
      "statement": "Quelle est la différence entre un chemin\n**absolu** et un chemin **relatif** ?",
      "options": [
        {
          "text": "L'un fonctionne uniquement sur Windows",
          "correct": false,
          "feedback": "Erreur : les deux existent sur tous les\nsystèmes d'exploitation.\n"
        },
        {
          "text": "L'un des deux est nettement plus rapide à utiliser",
          "correct": false,
          "feedback": "Erreur : performance équivalente.\n"
        },
        {
          "text": "L'absolu part de la racine `/`, le relatif du dossier courant",
          "correct": true,
          "feedback": "Bonne réponse : utiliser le bon selon\nle contexte. Le relatif est plus court\nmais ambigu hors contexte. L'absolu est\nrobuste mais long.\n"
        },
        {
          "text": "Aucune, les deux notations sont interchangeables partout",
          "correct": false,
          "feedback": "Erreur : la différence est fondamentale,\nun chemin relatif change de cible selon\nle dossier courant.\n"
        }
      ],
      "explanation": "Mnémonique : « absolu = depuis la\nracine » ; « relatif = depuis ici ».\nBonne pratique dans les scripts :\nprivilégier les chemins absolus pour\néviter les surprises."
    },
    {
      "id": "q20",
      "difficulty": 2,
      "skills": [
        "stdin-stdout-stderr"
      ],
      "title": "Entrée/sortie standards",
      "statement": "Que sont **stdin**, **stdout**, **stderr** ?",
      "options": [
        {
          "text": "Les trois flux standards : entrée, sortie et erreur",
          "correct": true,
          "feedback": "Bonne réponse : entrée (clavier), sortie\n(écran) et erreur (écran), descripteurs\nde fichier 0, 1, 2. Permettent les\nredirections : `>` (stdout), `2>`\n(stderr), `<` (stdin), `|` (chaînage\nstdin/stdout).\n"
        },
        {
          "text": "Trois variables d'environnement du système",
          "correct": false,
          "feedback": "Erreur : ce sont des flux de données,\npas des variables comme `PATH` ou `HOME`.\n"
        },
        {
          "text": "Trois systèmes d'exploitation dérivés d'Unix",
          "correct": false,
          "feedback": "Ces sigles ne désignent\naucun système d'exploitation.\nCe sont les trois flux\nstandards d'un processus\nUnix : entrée, sortie et\nsortie d'erreur.\n"
        },
        {
          "text": "Trois commandes Unix d'affichage de fichiers",
          "correct": false,
          "feedback": "Erreur : ce ne sont pas des commandes\n(l'affichage de fichiers, c'est `cat`,\n`less`...), mais des flux de données.\n"
        }
      ],
      "explanation": "Modèle Unix : tout programme a ces trois\nflux. C'est ce qui rend les pipes si\nnaturels. `prog 2>&1` redirige aussi les\nerreurs vers la sortie standard."
    },
    {
      "id": "q22",
      "difficulty": 3,
      "skills": [
        "chmod-octal"
      ],
      "title": "Permissions octales",
      "statement": "Que représente `chmod 755 script.sh` ?",
      "options": [
        {
          "text": "Des permissions codées en octal pour trois catégories d'utilisateurs",
          "correct": true,
          "feedback": "Bonne réponse : notation **octale**\ndes permissions Unix (4 = read, 2 =\nwrite, 1 = execute) : propriétaire\n`rwx` (7), groupe `r-x` (5), autres\n`r-x` (5).\n"
        },
        {
          "text": "L'identifiant du processus qui exécutera le script",
          "correct": false,
          "feedback": "Un identifiant de processus\n(PID) est attribué au\nlancement du programme,\nil n'a rien à voir avec\n`chmod`, qui modifie\nseulement les droits\nd'accès au fichier.\n"
        },
        {
          "text": "Une simple erreur de syntaxe de la commande",
          "correct": false,
          "feedback": "Erreur : syntaxe valide.\n"
        },
        {
          "text": "La nouvelle taille du fichier exprimée en octets",
          "correct": false,
          "feedback": "La commande `chmod` ne\ntouche jamais à la taille\ndu fichier. Elle ne modifie\nque les permissions, ici\nencodées en notation\noctale.\n"
        }
      ],
      "explanation": "Modes courants : 755 (exécutable\nlisible), 644 (fichier texte normal),\n700 (privé). À la place de la notation\noctale : `chmod u=rwx,go=rx script.sh`."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "synthese"
      ],
      "title": "Synthèse",
      "statement": "Parmi les affirmations suivantes sur le shell\nUnix, laquelle est **fausse** ?",
      "options": [
        {
          "text": "`grep` cherche un motif dans le contenu de fichiers",
          "correct": false,
          "feedback": "C'est exactement le\nrôle de `grep`. Cette\naffirmation est donc\njuste, et n'est pas\nla mauvaise réponse\nattendue dans cette\nquestion.\n"
        },
        {
          "text": "`rm` met les fichiers dans une corbeille récupérable par défaut",
          "correct": true,
          "feedback": "Faux (donc bonne réponse) : `rm`\nsupprime **définitivement** sans\ncorbeille en ligne de commande. La\ncorbeille est une notion graphique\n(gérée par l'environnement de bureau).\n"
        },
        {
          "text": "`pwd` affiche le chemin du dossier courant",
          "correct": false,
          "feedback": "Cette affirmation est\nexacte : `pwd` (*print\nworking directory*)\nrenvoie effectivement\nle chemin absolu du\ndossier courant. Ce\nn'est donc pas la\nmauvaise affirmation\nrecherchée.\n"
        },
        {
          "text": "`|` permet de chaîner des commandes en redirigeant la sortie de l'une vers l'entrée de l'autre",
          "correct": false,
          "feedback": "Vrai : un des concepts les plus\npuissants d'Unix.\n"
        }
      ],
      "explanation": "Important : `rm` est définitif. Toujours\nvérifier deux fois. La récupération est\npossible mais difficile (outils comme\n`extundelete`, `testdisk`)."
    },
    {
      "id": "q26",
      "difficulty": 1,
      "skills": [
        "chemin",
        "home"
      ],
      "title": "Le caractère « tilde »",
      "statement": "Dans un terminal Unix, à quoi correspond le caractère\n`~` (tilde) en début de chemin ?",
      "options": [
        {
          "text": "Au répertoire parent, situé juste au-dessus",
          "correct": false,
          "feedback": "Erreur : le répertoire parent se note `..` (deux\npoints). Le tilde n'a aucun rapport avec la\nremontée dans l'arborescence.\n"
        },
        {
          "text": "Au répertoire courant",
          "correct": false,
          "feedback": "Erreur : le répertoire courant est noté `.` (un\npoint). Le tilde renvoie au répertoire personnel,\nquel que soit l'endroit où l'on se trouve.\n"
        },
        {
          "text": "Au répertoire racine du système",
          "correct": false,
          "feedback": "Erreur : la racine se note `/`. Le tilde, lui,\nrenvoie à un répertoire personnel, pas à la\nracine du système.\n"
        },
        {
          "text": "Au répertoire personnel de l'utilisateur courant",
          "correct": true,
          "feedback": "Bonne réponse : `~` est une abréviation pour le\nchemin du répertoire personnel (par exemple\n`/home/eleve` sur Linux ou `/Users/eleve` sur\nmacOS). On peut donc écrire `cd ~/Documents`\nplutôt que le chemin absolu complet.\n"
        }
      ],
      "explanation": "Trois symboles à connaître pour la navigation : `~`\n(répertoire personnel), `.` (répertoire courant) et\n`..` (répertoire parent). On les combine fréquemment :\n`~/projets/.config` désigne le sous-dossier `.config`\ndu dossier `projets` placé dans le répertoire\npersonnel."
    },
    {
      "id": "q27",
      "difficulty": 2,
      "skills": [
        "glob",
        "joker"
      ],
      "title": "Caractère joker",
      "statement": "Dans un terminal, on saisit la commande suivante :\n\n```\nls *.txt\n```\n\nQuel est l'effet du caractère `*` ?",
      "options": [
        {
          "text": "Il remplace n'importe quelle suite de caractères dans un nom",
          "correct": true,
          "feedback": "Bonne réponse : avant l'exécution de la commande,\nle shell remplace `*.txt` par la liste de tous\nles fichiers du dossier courant dont le nom\nfinit par `.txt`. C'est le mécanisme appelé\n*globbing*.\n"
        },
        {
          "text": "Il multiplie le résultat de la commande par lui-même",
          "correct": false,
          "feedback": "Erreur : aucune notion d'arithmétique dans une\ncommande `ls`. Le `*` est un caractère générique\npour les noms de fichiers, pas un opérateur de\nmultiplication.\n"
        },
        {
          "text": "Il commente la fin de la ligne, ignorée par le shell",
          "correct": false,
          "feedback": "Erreur : un commentaire dans le shell s'introduit\navec `#` placé en début de ligne. Le caractère\n`*` est un joker pour l'expansion de noms de\nfichiers.\n"
        },
        {
          "text": "Il suspend l'exécution jusqu'à l'appui sur une touche",
          "correct": false,
          "feedback": "Erreur : la commande s'exécute normalement et\nliste bien des fichiers. Le caractère `*` ne\nbloque rien, il est simplement remplacé par les\nnoms qui correspondent au motif.\n"
        }
      ],
      "explanation": "Quelques motifs courants : `*.py` (tous les fichiers\nPython), `image_*.png` (toutes les images\nnumérotées), `*` (tous les fichiers du dossier).\nPlus précis : `?` remplace exactement un caractère\net `[abc]` remplace une lettre choisie dans\nl'ensemble."
    },
    {
      "id": "q28",
      "difficulty": 1,
      "skills": [
        "fichier-cache",
        "ls"
      ],
      "title": "Fichiers cachés",
      "statement": "Sous Unix, à quoi reconnaît-on un fichier ou un\ndossier dit **caché** ?",
      "options": [
        {
          "text": "À un attribut spécial dans le système de fichiers",
          "correct": false,
          "feedback": "Erreur : Unix n'utilise pas d'attribut\n« caché ». La convention est purement basée sur\nle nom : tout fichier dont le nom commence par\nun point est masqué par défaut.\n"
        },
        {
          "text": "À son extension `.hidden`",
          "correct": false,
          "feedback": "Erreur : aucune extension particulière ne marque\nun fichier comme caché. C'est le **préfixe** du\nnom (un point) qui joue ce rôle, pas\nl'extension.\n"
        },
        {
          "text": "À son nom qui commence par un point (par exemple `.bashrc`)",
          "correct": true,
          "feedback": "Bonne réponse : sous Unix, la convention est\nqu'un nom de fichier commençant par `.` n'est pas\naffiché par `ls` ni dans la plupart des\ngestionnaires graphiques. Pour les voir, on\nutilise l'option `ls -a`.\n"
        },
        {
          "text": "À son emplacement dans le dossier `/hidden`",
          "correct": false,
          "feedback": "Erreur : il n'existe pas de dossier réservé pour\nles fichiers cachés sous Unix. La convention est\nbasée sur le nom, pas sur l'emplacement.\n"
        }
      ],
      "explanation": "Cette convention est utilisée pour les fichiers de\nconfiguration personnels (`.bashrc`, `.gitconfig`,\n`.vimrc`) qui doivent rester discrets dans le\nrépertoire personnel. Pour visualiser ces fichiers\ndans un terminal, on utilise `ls -a`."
    },
    {
      "id": "q29",
      "difficulty": 3,
      "skills": [
        "synthese",
        "pipe",
        "redirection"
      ],
      "title": "Effet d'un enchaînement tube et redirection",
      "statement": "Que produit exactement la commande suivante ?\n\n`cat notes.txt | sort -n | head -n 3 > top3.txt`",
      "options": [
        {
          "text": "Elle écrit dans `top3.txt` les trois plus petites valeurs de `notes.txt`",
          "correct": true,
          "feedback": "Bonne réponse : le tube `|` enchaîne `cat` (lecture\ndu fichier), `sort -n` (tri numérique) et `head -n 3`\n(trois premières lignes du flot trié, donc les plus\npetites valeurs). La redirection `>` envoie ce flot\nfinal dans `top3.txt` : rien ne s'affiche dans le\nterminal et `notes.txt` n'est pas modifié.\n"
        },
        {
          "text": "Elle affiche les trois premières lignes de `notes.txt` à l'écran sans modifier les fichiers",
          "correct": false,
          "feedback": "Erreur : sans `sort`, on aurait peut-être pris les\ntrois premières lignes du fichier tel quel, mais le\ntri intervient avant `head`. Et la redirection `>`\nempêche tout affichage à l'écran.\n"
        },
        {
          "text": "Elle supprime les trois premières lignes de `notes.txt`",
          "correct": false,
          "feedback": "Erreur : `head` extrait des lignes mais ne modifie pas\nle fichier source. Aucune commande de suppression\nn'est utilisée ici.\n"
        },
        {
          "text": "Elle crée un fichier `top3.txt` contenant les trois premières lignes de `notes.txt` dans leur ordre d'origine, sans tri",
          "correct": false,
          "feedback": "Erreur : `sort -n` est appliqué avant `head`, donc\nles trois lignes écrites sont les plus petites\nvaleurs, pas les trois premières lignes du fichier\nd'origine.\n"
        }
      ],
      "explanation": "Les tubes `|` chaînent la sortie standard d'une commande\navec l'entrée standard de la suivante : chaque maillon\nfiltre ou transforme le flot. La redirection `>` capture\nenfin ce flot dans un fichier. Cette composition est\nl'un des principes les plus puissants du shell Unix."
    },
    {
      "id": "q30",
      "difficulty": 3,
      "skills": [
        "synthese",
        "find",
        "grep"
      ],
      "title": "Rechercher dans des fichiers",
      "statement": "Quelle commande permet de lister, dans le dossier\ncourant et tous ses sous-dossiers, les fichiers\nd'extension `.py` qui contiennent le mot `import` ?",
      "options": [
        {
          "text": "`grep -r --include='*.py' 'import' .`",
          "correct": true,
          "feedback": "Bonne réponse : `grep` parcourt récursivement (`-r`)\nle dossier courant `.`, limite la recherche aux\nfichiers correspondant au motif `*.py` grâce à\n`--include`, et affiche les lignes contenant le mot\n`import`.\n"
        },
        {
          "text": "`find . -name '*.py' import`",
          "correct": false,
          "feedback": "Erreur : `find` ne sait pas chercher de motif à\nl'intérieur des fichiers. Sans `-exec grep` (ou\néquivalent), le mot `import` est interprété comme un\nparamètre inattendu.\n"
        },
        {
          "text": "`find '*.py' | grep import`",
          "correct": false,
          "feedback": "Erreur : `find` attend un chemin de départ (souvent\n`.`), pas un motif global. De plus, `grep import`\nfiltrerait les **noms de fichiers** contenant `import`,\npas leur contenu.\n"
        },
        {
          "text": "`grep import *.py`",
          "correct": false,
          "feedback": "Erreur : la recherche est limitée au dossier courant\nuniquement, sans descendre dans les sous-dossiers,\nalors que l'énoncé exige une recherche récursive.\n"
        }
      ],
      "explanation": "`grep` est l'outil de recherche **dans le contenu** des\nfichiers ; `find` est l'outil de recherche **dans l'arborescence** (par nom, taille, date). Les deux se\ncombinent souvent : `find . -name '*.py' -exec grep -l\n'import' {} \\;` donne le même résultat que l'option\nretenue ici, en deux étapes."
    }
  ]
}