Il y a quelques mois, je postais une dépêche décrivant “GameShell”, un jeu que j’avais développé pour enseigner les bases de la ligne de commandes. Cette dépêche avait provoqué discussions, corrections de bugs et suggestions intéressantes.
Trois mois et quelques centaines de commits plus tard, je me permets de faire une petite mise à jour.
Globalement (mais je suis un peu biaisé), le GameShell d’aujourd’hui est nettement mieux que le GameShell d’hier. Ceci a un coût : la taille d’une archive GameShell a été multipliée par 3. On est passé de 44kio à 140kio !
Je ne sais pas comment on traduit “bloat” en français (“boursouflage” ?), mais pour le moment, ça ne m’empêche pas de dormir !
La version précédente avait été testée par plusieurs générations d’étudiants, parfois très inventifs. Alors n’hésitez pas à vous mettre dans la peau d’un étudiant en faisant une partie avant de me faire un retour.
Je suis preneur de toute critique, suggestion, rapport de bug, ticket, contribution et j’en passe.
Si certains veulent créer des missions, je pourrais faire une petite description de l’architecture d’une mission type. Ce n’est pas très compliqué, et une année, j’ai même eu un étudiant qui en a ajouté une comme « question bonus » !
Sommaire
Principe
L’idée derrière GameShell n’a pas changé : il s’agit d’effectuer des « missions » qui correspondent en fait à des opérations usuelles de gestion d’un ordinateur. Par exemple, « Cherchez le diamant dans le labyrinthe. » reviendra à chercher l’unique fichier contenant la chaine diamant
dans une arborescence.
Toutes les opérations se font dans un terminal en utilisant le shell (bash
en l’occurrence) et les commandes usuelles.
On lance une partie typique avec
$ ./gameshell.sh
____ ____ _ _ _
/ ___| __ _ _ __ ___ ___/ ___|| |__ ___| | |
| | _ / _` | '_ ` _ \ / _ \___ \| '_ \ / _ \ | |
| |_| | (_| | | | | | | __/___) | | | | __/ | |
\____|\__,_|_| |_| |_|\___|____/|_| |_|\___|_|_|
_
_/ \
_ / \
/ \_ __ /\/\ /\
/ \ / \ / \/ \
/\/\ /\ `--./.'- `-.\
/ \/ ' ^ _ _ _
/\ ____.. YY Y _ |~ _
/._/ _ \_ Y Y [_]--'--[_]
/ / .'/#\_ `-. Y YY |'|""`""|'|
.-_/#@##\ `\"" ' Y | | /^\ | |
" "'"''"'"'''" ' |_|_|I|_|_|
[mission 1] $
et on se retrouve dans une session bash
quasi normale.
Les seules opérations spécifiques sont celles relatives à la gestion des missions. Elles sont accessibles avec la commande spéciale gsh
(anciennement gash
, mais ce n’était pas approprié pour la version anglophone).
-
gsh goal
pour afficher l’objectif de la mission courante (anciennement,show
), -
gsh check
pour vérifier si la mission courante est finie, -
gsh reset
pour ré-initialiser la mission courante. (Pratique quand on a fait une bêtise…)
Il y a d’autres commandes (voir gsh HELP
pour une liste complète), mais elles ne devraient pas servir au joueur en temps normal.
[mission 1] $ gsh goal
,------------------------------------------------------.
(_\ \
| Objectif |
| ======== |
| |
| Allez tout en haut du donjon. |
| |
| |
| Commandes utiles |
| ================ |
| |
| cd LIEU |
| Se déplace vers le lieu donné. |
| Note : ``cd`` est une abréviation pour "change |
| directory". |
| |
| ls |
| Liste les lieux accessibles depuis la position |
| actuelle. |
| Note : ``ls`` est une abréviation pour "liste". |
| |
| pwd |
| Affiche la position actuelle. |
| Note : ``pwd`` est une abréviation pour "print |
| working directory". |
| |
| gsh reset |
| Ré-initialise la mission au début. |
| |
| |
| Remarque |
| -------- |
| |
| Les termes apparaissant en MAJUSCULES dans les |
| commandes sont des méta-variables : vous devez les |
| remplacer par des valeurs (chaines de caractères) |
| appropriées. |
_| |
(_/________________________________________________(*)___/
\
))
^
[mission 1] $ ls
Chateau Echoppe Foret Jardin Montagne
[mission 1] $ cd Chateau
[mission 1] $ ls
Batiment_principal Cave Donjon Grande_salle Observatoire
[mission 1] $ cd Donjon
[mission 1] $ ls
Premier_etage
[mission 1] $ cd Premier_etage
[mission 1] $ ls
Deuxieme_etage
[mission 1] $ cd Deuxieme_etage
[mission 1] $ ls
Haut_du_donjon
[mission 1] $ cd Haut_du_donjon
[mission 1] $ ls
[mission 1] $ gsh check
Bravo, vous avez réussi la mission 1 !
[mission 2] $
Il y a actuellement 42 missions. Pour vous donner une idée, mes bons étudiants arrivent autour de la mission 35 en 2h30.
Lancement d’une partie
La distribution d’une archive GameShell (c’est-à-dire le code GameShell avec une liste de missions) a été simplifiée. Au lieu d’une archive usuelle au format .tgz
(qu’il fallait donc désarchiver avant de pouvoir lancer une partie), j’utilise une « archive auto-extractante » : un fichier unique contenant un entête « script » et l’archive en binaire. L’entête extrait la partie « archive » dans un fichier temporaire, utilise tar -xf
et lance le jeu. Lorsqu’on quitte, une archive est régénérée et intégrée au script, permettant de reprendre facilement la partie à la mission courante.
Une telle archive est générée automatiquement par github lors des commits sur la branche master:
https://github.com/phyver/GameShell/releases/download/latest/gameshell.sh
Le code de GameShell contient un script utils/archive.sh
pour générer ses propres archives si l’on souhaite supprimer des missions, en changer l’ordre, etc.
Internationalisation
Un ticket ouvert sur github demandait si j’avais l’intention de traduire GameShell.
Ce n’était pas au programme, mais Rodolphe Lepigre (qui avait eu l’idée originale de GameShell) a fait une pull-request en disant : « regarde, c’est facile ».
Résultat, j’ai mis mes corrections de TP en suspens et me suis mis à bosser sur GameShell ! (Ne vous en faites pas, j’ai repris mes corrections par la suite…)
GameShell est donc maintenant officiellement disponible en anglais ou français. La langue dépend de votre locale, plus précisément de la variable LC_MESSAGES
. Si c’est autre chose que en_..
ou fr_..
, c’est l’anglais qui sera utilisé.
Sur les systèmes GNU, on peut changer la langue simplement en donnant l’option -L fr
ou -L en
au lancement de GameShell. (On peut même donner plusieurs langues par ordre de préférence, style -L it:fr:en
, mais ça ne sert pour le moment à rien vu que les seules langues supportées sont fr
et en
et que tous les messages sont traduits.)
Pour les systèmes non GNU (comme macOS), il faudra spécifier une locale valide à la main :
$ LC_MESSAGES=fr_FR.utf8 ./gameshell.sh
(Vous pouvez utiliser la commande locale -a
pour obtenir la liste des locales supportées par votre système.)
Les messages sont choisis par gettext
et les traductions sont donc indépendantes du code de GameShell ou des missions. Pour ceux qui ne connaissent pas, au lieu de
echo "Error: wrong password."
le code de GameShell contient
echo "$(gettext "Error: wrong password.")"
La commande gettext
va chercher le message correspondant à "Error: wrong password."
dans la langue courante. Si aucune traduction n’est trouvée, gettext
renverra son entrée et le message sera donc affiché en anglais.
De la même manière,
mkdir Castle
est remplacé par
mkdir "$(gettext "Castle")"
etc.
Outre les fichiers texte donnant les descriptions des missions (ou les messages d’aide), les traducteurs doivent gérer des fichiers du style
...
msgid "Error: wrong password."
msgstr "Erreur : mauvais mot de passe."
msgid "Error: you are not allowed to run this command."
msgstr "Erreur : vous n'avez pas le droit d'exécuter cette commande."
msgid "Is this information correct? [Y/n]"
msgstr "Est-ce que ces informations sont correctes ? [O/n]"
...
Aucune connaissance en programmation shell n’est donc nécessaire pour faire ces traductions.
Dépendances
Les versions initiales de GameShell avaient des dépendances surprenantes, notamment
- Python3
gcc
x11-utils
gcc
et x11-utils
étaient en fait des dépendances sur des missions particulières, qu’on pouvait ne pas inclure dans une archive.
Les missions peuvent maintenant vérifier leurs dépendances. S’il manque quelque chose, la mission est simplement annulée.
La dépendance sur Python3 a été entièrement supprimée. Les scripts Python ont été, pour la plupart, ré-écrits en awk
. Je ne dis pas que awk
est mieux que Python, mais il a l’avantage d’être requis par la norme POSIX et il est installé par défaut sur les plateformes cibles de GameShell. (Linux, BSD, macOS)
Je ne connaissais pas beaucoup (à part l’occasionnel ... | awk '{print $4}'
), mais c’est finalement un langage assez marrant.
Au final, la seule dépendance "forte" pour GameShell est bash
(mais on pourra bientôt utiliser zsh
à la place), et si on veut jouer dans une autre langue que celle de Shakespeare, gettext
. Il faut aussi avoir un système POSIX avec les utilitaires standards (ls
, cp
, tail
, grep
, etc.)
POSIX
En interne, le code a été modifié pour favoriser les solutions POSIX. La raison est que cela simplifie la gestion des différentes plateformes cibles pour GameShell (Linux, BSD, macOS).
Dans un souci de simplification, la plupart des fonctions utilisées par GameShell sont maintenant externalisées dans des scripts indépendants. (cf dossier bin/
)
Cela a été l’occasion d’apprendre pas mal de trucs et de voir les avantages (mais aussi les limites) de la norme POSIX.
Normalement, il n’y a plus beaucoup d’endroits où du code spécifique est nécessaire :
- sauvegarde de l’environnement (obtenir la liste des variables d’environnement et des fonctions du shell de manière portable) : script
bin/save_environment.sh
, - gestion des processus (la commande
ps
utilise des options différentes sur les différentes plateformes, et même la partie standardisée n’est pas respectée) : missions du groupeprocesses
, - des scripts de tests (
auto.sh
ettest.sh
) de missions qui insèrent des commandes dans l’historique à la main (bash
sait faire ça).
PS
Pour ceux qui ont lu jusque-là et qui font une partie, les commandes « admin » (voir gsh HELP
) ont besoin d’un mot de passe.
Par défaut, c’est « gsh » (comme la commande).
Ça peut servir en cas de bug qui ne permet plus de valider une mission. On peut utiliser gsh skip
pour la sauter !
Aller plus loin
- GameShell sur Github (434 clics)
- README en français (197 clics)
- archive pour faire une partie (237 clics)
# Super initiative
Posté par abriotde (site web personnel, Mastodon) . Évalué à 3.
Je connaissait pas c est super comme initiation à Linux, pour motiver un jeune 15 ans. Je vais l essayer.
Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.
[^] # Re: Super initiative
Posté par phyve . Évalué à 4.
Super !
N'hésite pas à faire un retour. Les utilisateurs complètement novices ne voient pas du tout les mêmes choses que les utilisateurs plus avancés.
[^] # Re: Super initiative
Posté par orfenor . Évalué à 7.
Après ta première dépêche j'ai fait faire le jeu à mes gamins (12 et 13). Ils ont eu énormément de mal avec … la casse. Et en effet, dans les instructions de base de la première mission, c'est pas facile de comprendre pour un novice que
cd LIEU
doit respecter la casse.Entre parenthèse, j'ai utilisé ton jeu pour négocier leur temps d'écran. Très efficace.
[^] # Re: Super initiative
Posté par phyve . Évalué à 3.
J'ai jamais eu ce problème avec mes étudiants, mais ça mérite une remarque. Je viens d'ajouter une phrase dans le fichier
goal
de la première mission.# tree
Posté par pamputt . Évalué à 4.
Félicitations pour le logiciel. Je suis en train de préparer un pull request avec des corrections pour les erreurs de traduction ou des typo.
Concernant la mission 20, il propose d'utiliser la commande « tree » qui est en effet très pratique. Sauf que je viens de voir que « tree » n'était pas installé par défaut sur mon système. Du coup, il faudrait peut-être le traiter comme une dépendance. À noter qu'on peut toujours utiliser "ls -R" comme indiqué.
[^] # Re: tree
Posté par phyve . Évalué à 4.
Merci, je regarde ta pull-request bientôt.
Pour
tree
, je crois que j'ai déjà changé d'avis plusieurs fois. Je trouve effectivement que cette commande est bien pour visualiser l'arborescence et est vraiment utile pour les débutants (mes étudiants).D'un autre coté, la mission sert aussi à préparer les missions suivantes, et ça serait dommage de la sauter.
Pour le moment, je mets
tree
dans la liste des paquets à installer (dans leREADME
), mais ne considère pas cette commande comme une dépendance stricte. (C'est pour ça que j'ai ajoutéls -R
dans le fichiergoal
.)Ton commentaire va peut-être me faire changer d'avis, encore une fois. :)
# Mission 28
Posté par pamputt . Évalué à 4. Dernière modification le 26 juin 2021 à 22:56.
Je ne suis pas sûr d'être arrivé au bout de la mission 28 correctement. En fait pour réussir, j'ai killé un processus bash. Mais lorsque j'ai fait "gsh check", ça m'a affiché
Pas sûr que les deux premières lignes soient celle attendues.
[^] # Re: Mission 28
Posté par phyve . Évalué à 3.
Ah…
Ces missions m'en font voir de toutes les couleurs.
Je regarde ça.
[^] # Re: Mission 28
Posté par phyve . Évalué à 4.
C'est normalement corrigé !
# Mission 31
Posté par pamputt . Évalué à 4.
Bonjour, voici ce que j'ai obtenu dans la mission 31
J'ai tapé "79*9" juste pour tester. Normalement ça ne fonctionne pas, mais là ça m'a dit que j'avais bon :S
[^] # Re: Mission 31
Posté par phyve . Évalué à 3.
Ça, c'est clairement un bug. Il faut normalement répondre à 100 multiplications !
Je regarde ça cette après-midi.
[^] # Re: Mission 31
Posté par phyve . Évalué à 4.
C'est normalement corrigé.
# Suppression de Python
Posté par riri le breton (site web personnel) . Évalué à 2.
Merci d'avoir travaillé sur ça ! C'est le genre de dépendance qui me fait sortir les yeux des orbites.
Je n'ai pas testé les nouveautés, mais lors de la précédente dépèche j'avais essayé le jeu et j'avais bien aimé, même si j'ai juste essayé vite fait.
[^] # Re: Suppression de Python
Posté par phyve . Évalué à 5.
Tout est une question de point de vue.
J'utilise Python, et mes étudiants aussi. Cette dépendance ne me choquait donc pas. (Mais je suis content de m'en être débarrassé.)
Par contre, une dépendance sur Ruby (au hasart) m'aurait choqué, et une dépendance sur
nodejs
m'aurait carrément convaincu d'aller voir ailleurs ![^] # Re: Suppression de Python
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2.
Je fais partir des personnes ayant râlé contre les dépendances, et suis donc ravi que ce soit maintenant de vieux souvenirs.
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: Suppression de Python
Posté par phyve . Évalué à 3.
Même si les dépendances ne me dérangeaient pas, je suis aussi content de les avoir supprimées.
Et les supprimer m'a fait découvrir plein de trucs.
# Quelques remarques
Posté par Cascador (site web personnel) . Évalué à 3.
Salute,
Excellente initiative et jeu sympa, merci ^
Quelques remarques :
- Vous devez trouver ce sortilège et le tenter de le supprimer => et tenter de le supprimer
- Désolé, la mission 28 a échoué => La tournure est bizarre, "Désolé, vous avez échoué"
- Un petit bug
Tcho !
[^] # Re: Quelques remarques
Posté par phyve . Évalué à 2. Dernière modification le 03 juillet 2021 à 13:07.
Merci, c'est corrigé.
Pour le message, tu as effectivement raison, mais je voulais éviter un truc "négatif" pour le joueur. Je vais chercher une autre formulation. :)
[^] # Re: Quelques remarques
Posté par orfenor . Évalué à 3.
[^] # Re: Quelques remarques
Posté par ted (site web personnel) . Évalué à 6.
Tu n'a pas échoué, c'est juste que ta tentative n'a pas marché
Un LUG en Lorraine : https://enunclic-cappel.fr
[^] # Commentaire supprimé
Posté par Anonyme . Évalué à 3.
Ce commentaire a été supprimé par l’équipe de modération.
# Bravo !
Posté par Sébastien Bonnegent . Évalué à 2.
Et merci pour ce projet (et cet article qui m'a permis de le découvrir). Les missions sont intéressantes et motivantes pour les débutants. Cela donne à réfléchir pour créer des nouvelles missions :)
J'ai fait avec plaisir les 42 missions :)
[^] # Re: Bravo !
Posté par phyve . Évalué à 2.
Content que tu ais aimé !
Et n'hésite pas à créer de nouvelles missions. Tu verras, ce n'est pas très compliqué.
# Interface graphique nécessaire?
Posté par laplongejunior . Évalué à 2.
Ma seule machine non-Windows est "headless" (contrôlée à distance sans interface graphique)
Est-ce que GameShell peut être utilisé via uniquement un accès ssh?
[^] # Re: Interface graphique nécessaire?
Posté par phyve . Évalué à 4.
Sans problème. Il y a une seule mission qui nécessite X, et elle sera sautée si la variable
DISPLAY
n'est pas définie.Vérifie que tu as les dépendances des autres missions (
gettext
man-db
psmisc
nano
tree
etbsdmainutils
), et$ wget https://github.com/phyver/GameShell/releases/download/latest/gameshell.sh
$ bash gameshell.sh
fonctionnera sans problème à distance.
# Nouvelle aventure
Posté par orfenor . Évalué à 3.
Je réfléchis à une nouvelle aventure1 (le nom que je donne à un ensemble de missions), et me pose quelques questions :
Les commandes apprises dans la premières aventures (GameShell Basic) :
une sorte de chasse au trésor pour apprendre à mes enfants comment résoudre leurs problèmes d'installation d'extensions et lanceurs Minecraft sans papa. ↩
[^] # Re: Nouvelle aventure
Posté par phyve . Évalué à 3. Dernière modification le 17 juillet 2021 à 23:21.
Il n'y a pas vraiment d'ordre pour les "aventures". L'idée est que
basic
doit venir en premier pour apprendre à se déplacer dans le monde de GameShell et de manipuler les fichiers.Pour la suite, rien n'est imposé, mais les missions d'une aventure doivent a priori être faites dans l'ordre et suivre une progression, alors que les aventures sont indépendantes entre elles.
L'aventure
finding_files_maze
par exemple, est découpée en 2 morceaux dans l'archive "officielle" : une première partie où on utilise simplementfind
(missions 19-21), et une seconde où on combinefind
avec d'autres trucs (missions 38-39).J'ai l'impression qu'il ne manque pas grand chose dans l'aventure
basic
(commandes et concepts de base).Les trucs à faire sont soit des missions "singletons", à mettre dans "
misc
" (pour des trucs divers, pas forcément standards : par exemple, la commandeseq
oufactor
, ouwatch
) ou "intermediate
" (pour des trucs standards compatibles POSIX : par exemple des motifs avancés avec*.??[!gG]
, la commandetee
).Les missions des ces 2 aventures sont essentiellement indépendantes entre elles.
D'autres concepts méritent une aventure spécifique avec plusieurs missions : liens symboliques, expressions régulières, etc.
Globalement, GameShell vise plutôt à enseigner l'utilisation interactive du shell. J'aimerais bien ajouter une ou deux missions pour montrer les boucles simples sur les fichiers, mais je n'ai pas l'intention d'aller beaucoup plus loin sur l'écriture de scripts.
Et même s'il n'y en a pas pour le moment, rien interdit d'avoir des mission qui introduisent des trucs spécifiques à bash ou zsh (les 2 shells supportés).
# Lien erroné
Posté par orfenor . Évalué à 3.
Lien erroné dans la première phrase «Il y a quelques mois, je postais une dépêche décrivant» il manque le signe deux points après https et il y a http en plus (on peut d'ailleurs supprimer toute la partie avant
/news
)[^] # Re: Lien erroné
Posté par Benoît Sibaud (site web personnel) . Évalué à 4.
Corrigé, merci.
[^] # Re: Lien erroné
Posté par orfenor . Évalué à 2. Dernière modification le 17 juillet 2021 à 18:10.
je ne savais pas qu'un lien
//linuxfr.org/news/…
pouvait marcher. Ça n'a pas l'air de gêner Firefox.[^] # Re: Lien erroné
Posté par Benoît Sibaud (site web personnel) . Évalué à 5. Dernière modification le 17 juillet 2021 à 19:55.
L'erreur que j'ai corrigée c'était un lien
http://https://linuxfr.org/...
(niveau markdown en tout cas, je n'ai pas regardé le HTML généré).Mais pour répondre à ta question : http://linuxfr.org c'est linuxfr.org en HTTP, https://linuxfr.org c'est le même en HTTPS, et //linuxfr.org c'est toujours le même mais en HTTP ou HTTPS suivant ce qui est actuellement utilisé (protocol-relativ). Mais bon ça n'a plus trop la côte, cf https://linuxfr.org/suivi/liens-image-protocol-relative-implicit-dans-les-flux
# gsh_gettext.sh Aucun fichier ou dossier de ce type
Posté par ah . Évalué à 1.
J'ai une debian 10 buster
apt install gettext-base man-db psmisc nano tree bsdmainutils x11-apps
wget https://github.com/phyver/GameShell/releases/download/latest/gameshell.sh
$ bash gameshell.sh
bash: gsh_gettext.sh: Aucun fichier ou dossier de ce type
bash: eval_gettext : commande introuvable
bash: eval_gettext : commande introuvable
check, goal, help, reset
[mission ] $
[^] # Re: gsh_gettext.sh Aucun fichier ou dossier de ce type
Posté par phyve . Évalué à 2.
Je n'arrive pas à reproduire ce bug, même à partir d'une installation vraiment minimale.
Ton bug donne l'impression que les chemins d'accès ne sont pas définis correctement.
Est-ce que tu peux me donner les résultats des commandes suivantes (lancées depuis GameShell) :
[mission ] $ echo $GSH_ROOT
???
[mission ] $ echo $PATH
???
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.