================================================================
INFO 1 - Systèmes d’Exploitations - TP0 - Commandes Unix de base
================================================================


Avant-propos
------------

Le but de ce TP est de devenir vraiment à l’aise avec l’interface en ligne de
commande de type Unix (en général une distribution GNU+Linux, mais si vous êtes
sur une variante de BSD, ok).

Pour ce faire, il est mieu de connaître un minimum l’interface graphique
utilisée, ainsi ses raccourcis clavier (notamment vers le terminal (quel
terminal ?)).

On suppose que vous êtes à l’aise en français et en anglais, mais s’il y a un
problèmes, ne pas hésiter à demander un éclaircissement.

On suppose également que vous avez lu le cours avant de venir, mais au cas où,
il se trouve ici <https://lipn.univ-paris13.fr/~dufour/se/cm/>.

Il est, de plus, conseillé de bien ranger ses cours & TP dans son répertoire,
par exemple :

```
Documents
├── ProgC
│   ├── Cours
│   ├── TD
│   └── TP
├── ProgSci
│   ├── Cours
│   ├── TD
│   └── TP
└── SE
    ├── Cours
    └── TP
        ├── 0
        ├── 1
        └── 2
```

Enfin, en cas de doutes existentiels profonds, regarder les pages de manuels
avec `man` (quitte à faire `man man`), et
- si vous ne comprenez pas une commande et qu’elle a l’air de faire peur, vous
  pouvez toujours demander son avis à <https://explainshell.com/>
- de même si vous voulez vérifier la justesse d’un script shell :
  <https://www.shellcheck.net/> (qui est une interface à un programme haskell
  qui peut parfaitement tourner localement).



Quelques jeux
-------------

Si les notions de chemins (absolus, relatifs, liens symboliques) vous sont
encore un peu floues, _Find your path_ est un jeu pédagogique développé par
Thierry Excoffier à l’université Claude Bernard Lyon 1. En voici l’URL pour y
jouer dans un navigateur web : <http://demo710.univ-lyon1.fr/FYP/>.
Inutile d’y passer trop de temps non plus.

Si vous êtes confiant·es, passez au _GameShell_, développé par Pierre Hyvernat
(université Savoie Mont-Blanc) et Rodolphe Lepigre. Téléchargez la version
locale et essayez de le speedrunner.

```sh
$ wget 'https://lipn.univ-paris13.fr/~dufour/se/rsrc/gameshell.sh'
$ bash gameshell.sh
```

Pour reprendre une partie en cours, on pourra utiliser `./gameshell-save.sh`.
Le code source est disponible sur <https://github.com/phyver/GameShell>.

À des fins de programmation et d’administration système, choisir un éditeur de
texte convenable (léger), on conseillera `kate` pour un éditeur graphique, et
`vim` pour un éditeur en ligne de commande, à cette fin, vous pouvez essayer de
faire le `vimtutor` pour voir si vous en appréciez la philosophie (il existe
d’autres, notamment `emacs`, `nano`, …, le but est d’être à l’aise, de connaître
les raccourcis clavier, et d’avoir de la colorisation syntaxique).


Exploration du système
----------------------

Identifier :

- nom de connexion et de la machine,
- UID et GID,
- liste des utilisateur·ices connecté·es à la même machine que
  vous,
- l’architecture et le boutisme du processeur de votre machine,
- l’endroit où est configuré votre prompt,
- l’endroit où est configuré votre éditeur de texte préféré
  * pour vous
  * pour tout le monde


Quelques exos supplémentaires sur les utilitaires classiques
------------------------------------------------------------

Les utilitaires classiques, très appréciables en eux-mêmes, encore mieux avec de
la redirection de flux (`|`, `<`, `>>`, …) :

- `grep` : qui permet de faire des recherche de mots, *globbing patterns* ainsi
  que *regex* (expréssion régulières) dans un ou plusieurs fichiers textes. De
  nombreuses options existent évidemment, les plus classiques étant `-i`, `-v`,
  `-q`, `-H`, `-n` (cf. `man grep`).

- `find` : qui permet de chercher des fichiers dans l’arborescence, les options
  répandues étant :
  * `-type c`, où c est dans bcdpfls (on retiendra d pour dossier et f pour
    fichier normal)
  * `-name` : pour le nom (*globbing pattern*)
  * `-exec` : pour exécuter une commande sur les fichiers trouvé (voir la
    syntaxe dans le manuel) ;

- `cut` : filtre pour sélectionner des colonnes dans un fichiers avec
  séparateurs de champs, avec comme options `-d` pour spécifier le séparateur et
  `-f` pour sélectionner les champs ;
- `sort` : pour trier, `-u` pour n’avoir qu’une occurrence de chaque entrée,
  peut prendre en compte les séparateurs via `-t` et les champs via `-k` ;
- `tr` : pour convertir des caractères ;
- `sed` : pour éditer en flux (sélectionner des lignes, chercher-remplacer avec
  des *regex*, …), mais on ne l’utilisera pas trop.

Télécharger <https://lipn.univ-paris13.fr/~dufour/se/rsrc/auto> et :

1. Afficher la liste des véhicules gris (grep sur le fichier auto).
2. Afficher la liste des modèles d’auto (2e champ).
3. Trier le fichier auto.
4. Trier les autos en fonction du modèle.
5. Afficher la liste des véhicules de l’année ’89.
6. Afficher la liste des véhicules qui ne sont pas rouges.
7. Afficher toutes les couleurs d’autos du fichier (une seule fois).

Au besoin, pour l’affichage dans le terminal, remplacer les séparateurs de
champs peu lisibles par des tabulations.


Remarque générale
-----------------

De manière particulièrement annexe, chaque langage de programmation a plusieurs
style de code possible (indentation, accolades, …), et donc la plupart des
projets imposent (plus ou moins strictement) un _style de code_.

Par exemple :
* [Linux Kernel](https://www.kernel.org/doc/html/v4.10/process/coding-style.html)
* [OpenBSD](https://man.openbsd.org/style)

Il existe évidemment des utilitaires pour “normaliser” du code, notamment en C.
Par exemple `indent`, qui, avec l’option `-linux`, permet d’uniformiser le style,
et de le conformer à celui de la communauté développant le noyau Linux.

Si vous avez beaucoup de code un peu sale, entre `find` avec le bon chemin et
les bonnes options, et `indent`, il y a moyen de faire le ménage.


Droits d’accès
--------------

Créer un dossier dans lequel vos collègues étudiant·es peuvent accéder mais pas
lister le contenu.

Y mettre quelques fichiers ou dossier que vous voudriez leur leur partager
(énoncés de tp, fichier de configuration bash ou vim…), mais sans être
modifiable.

Y créer un dossier dont le contenu est éditable par toustes, et demander à
quelques collègues d’y mettre quelque chose (pas de trop mauvaises surprises
non plus, autant en terme d’espace que de contenu).

Si l’on est en panne d’inspiration pour le partage de fichier, des fichiers
vides créés avec `touch` feront l’affaire.

Si l’on est en panne d’ami·es, la commande de changement de propriétaire `chown`
pourra aider, un peu.







Shell scripting
---------------

Le shell est doté —en plus de tous les programmes du système, et de redirections
de flux— de quelques mots-clefs et constructions internes qui en font un langage
de programmation même sans recours au programmes du système.

Un exemple vaut mieux qu’un long discours :

```sh
#!/bin/sh

SAVEDIR="${HOME}/Templates/Mans"
mkdir -p $SAVEDIR

for info in /usr/share/info/*.info.gz
do
	man="${info##*/}"
	man="${man%.info.gz}.man"
	info2man "${info}" 1> "${SAVEDIR}/${man}" 2> /dev/null
done
```

où l’on constate que l’on peut créer des variables, faire une liste de commande
comme d’habitude ; où les boucles bouclent sur une liste séparée par des
espaces, quitte à être passé à la moulinette de l’expansion de *globbing
patterns*, et où l’on peut également manipuler le contenu d’une variable avec
des *globbing patterns* pour la découper (“parameter expantion”).

Évidemment, chaque shell a sa syntaxe, le dénominateur commun étant la version
POSIX, et la plus courante étant celle de `bash`.


Plomberie avancée
-----------------

<https://tldp.org/LDP/abs/html/io-redirection.html>


Installation et configuration locale
------------------------------------

<https://tools.suckless.org/dmenu/>

1. Télécharger la *tarball* ou cloner le dépôt *git*.
2. Désarchiver si nécesssaire (`tar xvf`, avec un `z` en plus avant le `x` si
   l’archive est compressée). Compiler (`make`). Tester.
3. Jeter un coup d’œil au *Makefile* et au *config.h*, modifier ce dernier si
   des inspirations particulières vous prennent.
4. Patcher le code source pour pouvoir lancer `dmenu` de manière centrée.
5. Faire un petit script shell qui trouve tous les fichiers intéressants (pour
   vous) de votre répertoire préféré, vous demande d’en choisir un, et le lance
   une fois que ce choix est fait.
6. Trouver comment lier ce script exécutable à un raccourcis clavier de votre
   environnement de bureau.


Customisation du ~/.bashrc
--------------------------

Le `bashrc` et le fichier dans lequel se font la plupart des customisations du
shell, notamment les alias, les variables d’environnement, les fonctions, …

Certaines variables d’environnement sont utilisées par d’autres programme comme
défaut, on pensera au PATH, mais aussi des qui servent à définir son éditeur de
texte préféré :

```sh
export EDITOR=/bin/vim
export VISIUAL=...
export BROWSER=firefox
```

Une autre idée et de mettre une ligne qui affiche un message de bienvenu à
chaque nouveau terminal d’ouvert (message ou bien ASCII Art).

Et, bien évidemment, le prompt, qui donne des informations intéressantes,
peut se voir augmenter de l’heure, la date, ou bien le statut de sorti de la
dernière commande, la branche `git` dans laquelle on se trouve. Rajouter moult
couleurs pour différencier différentes connexions distantes…

<https://wiki.archlinux.org/title/Bash/Prompt_customization>


Customisation avec des néons
----------------------------

Couleurs dans le `man`, via le `~/.bashrc` :

```sh
export PAGER="less"
export GROFF_NO_SGR=1

# support colors in less
export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;31m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;44;33m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;32m'
# raw control characters
export LESS=' -R '

# export MANWIDTH=80
```

Pour coloriser la sortie de différentes commandes, plusieurs solutions,
certaines ont une option pour cela :

```sh
alias diff='diff --color=auto'
alias egrep='grep -E --color=auto'
alias fgrep='grep -F --color=auto'
alias grep='grep --color=auto'
alias ip='ip -color=auto'
```

(à mettre dans `~/.bashrc` évidemment).

Une autre solution et un *colorizer* tel que
[GRC](https://github.com/garabik/grc) (attention, `ls` devient partiellement
moche, il est possible de sélectionner lesquels on colorise, ouf).

Et pour finir, le *thème de couleur* non seulement du terminal, mais aussi
d’autres composants graphique, peuvent être extrait de vos fond d’écrans
préférés : <https://github.com/dylanaraps/pywal>.


Disk Destroyer
--------------

ATTENTION : les commandes suivantes sont dangeureuses à manipuler, dans le sens
où elles détruisent des données, ce qui est leur but.

La commande `dd` permet de faire des écritures *bit-à-bit*, pratique pour :
- créer des fichiers de taille arbitraire, rempli de 0 (`/dev/zero`), ou
  d’aléatoire de qualité (`/dev/random`),
- écraser des fichiers, y compris des partitions ou des disques entiers (via
  `/dev/sdb3`, `/dev/sda`, `/dev/mmcl0p2`, …) avec des zéros ou de l’aléatoire.

Une de ses utilisations est également faisable via `shred`, qui ne supprime pas
un fichier, mais écrit n’importe quoi dedans.

La NSA recommande d’écrire et réécrire zéros ou aléatoire une vingtaine de fois
sur un disque (avant de le détruire physiquement) pour être sûr que les données
ne soient plus exploitables. Pour des gens normaux ou des services de polices
normales, trois ou quatre fois est déjà pas mal.


Récupération disque
-------------------

À l’inverse, si des données sont supprimées, via `rm` par exemple, il est
possible de faire de l’exploration du disque (ou autre périphérique de stockage
tel que clefs USB, carte (micro)SD, …) pour retrouver les données. Pour en
retrouver un maximum, ne plus écrire sur le périphérique en question.

Faire une sauvegarde de la partition `cat /dev/sdXN > sauvegarde-date.img`, ou
juste du périphérique (sans le numéro de partition). On peut également utiliser
`pv` (non-standard, à installer) pour voir la barre de progression (marche de
manière générale dans les *pipes*). Ou encore `dd if=/dev/sdXN
of=sauvegarde-date.img`.

Ensuite, sur le périphérique ou la sauvegarde, retrouver les fichiers nécessite
de le lire intégralement (secteur par secteur), le repérage se fait via
l’identificateur de début de fichier (*magick numbers*), et dépend donc du
système de fichier utilisé sur la partition, retrouve aussi les fichiers dans
les corbeille, les fichiers supprimés volontairement il y a plus ou moins
longtemps, les fichiers systèmes dont on se fout…

`photorec`


Exo fusion des deux pavés précédents
------------------------------------

Nécessite de pouvoir être root.

1. Créer un fichier de 100M de zéros avec `dd` (copiés par bloques de 1M par
   exemple).
2. Y installer votre système de fichier préféré, par exemple EXT4, via `mkfs`.
3. “Monter” le volume de stockage ainsi créé sur un dossier prévu à cet effet
   (`mount`).
4. Vérifier qu’il est bien dans la liste des *block devices* sur le bon point de
   montage avec le bon système de fichier avec `lsblk` ou `findmnt`.
5. Y créer/copier des fichiers de tailles et contenus variées.
6. En supprimer certains, en *détruire* d’autres (sans forcément les supprimer).
7. Voir si vous pouvez retrouver les fichiers supprimés avec des méthodes
   discutées précédemment.


Idées de bidouilles
-------------------

1. Avoir une machine qui peut tourner 24/7 (Raspberry Pi, vieux PC, …).
2. Y installer une distribution linux orienté serveur dessus. Choix classiques :
   - Debian, une des plus vieille, très pratique, très généraliste,
   - Alpine, très légère et très minimaliste, davantage de bidouille nécessaire
     parfois.
3. Arriver à y accéder via `ssh` est obligatoire, inutile d’y installer une
   interface graphique, donc.
   On génère une paire de clef via `ssh-keygen`, on met dans `~/.ssh/config` un
   petit nom/alias qui pointe sur l’IP de la machine en question (ou son nom
   domaine, voir après), et qui indique quel clef privée on utilise.
   Sur la machine “distante”, on met la clef publique ssh dans
   `/root/.ssh/authorized_keys`, on fait en sorte que les connections par mot de
   passe soient impossible dans la configuration du dæmon ssh (`/etc/sshd/`).
4. Et maintenant, on s’y connecte à distance via `ssh`, et on peut se mettre à
   l’aise (fichier de conf’ bash pour le prompt et les alias), et on installe,
   par exemple :
   - `nginx`, serveur http, pour pouvoir héberger des sites web,
   - `certbot`, pour avoir un certificat *Let’s Encrypt*, on aura du httpS,
   - un dæmon BitTorrent si on veut participer à la culture libre (et qu’on a de
     l’espace disque),
   - `bind`, implémentation du protocole DNS, en mode serveur faisant authorité
     si on veut gérer ses sous-domaines soi-même, en mode résolveur sinon (cf.
     listes de blocages & résolveurs DNS alternatifs sur sebsauvage.net).
   - `ircd`, un dæmon IRC, pour l’ancêtre lointain (et libre) de discord & co,
   - le dæmon matrix, pour une alternative libre et moderne de discord & co,
   - une instance `invidious` pour un front-end plus sympa à youtube.com,
   - une instance `peertube` pour son propre youtube,
   - une instance `mastodon` pour son propre twitter/x,
   - `ipfs`, Inter Planetary File System,
   - `git`, pour avoir votre propre forge logicielle (github),
   - `0x0`, pour avoir votre propre *pastbin*,
   - `minetest`, jeu libre et serveur alternatif à minecraft…
5. Réserver un ou plusieurs nom de domaine, sur netlib.re par exemple, les lier
   à l’adresse IP publique de votre machine (A pour v4, AAAA pour v6), y faire
   d’autres enregistrements si vous voulez (regarder DNSSEC, DMARC et DKIM pour
   les serveurs mails, …).
6. Évidemment, il est possible de créer plein d’utilisateur·ices sur votre
   machine, y mettre leur clef publiques pour qu’iels puissent utiliser `sshfs`,
   et ainsi faire office de serveur SFTP.

Ressources & tutos intéressants : <https://landchad.net>


Les vimistes parlent aux vimistes
---------------------------------

- [tuto rapide mais avancé](https://fabi1cazenave.github.io/slides/2017-vim-ducklings/2-enlightenment.html#1)
- [vimrc minimal](https://www.guckes.net/vim/setup.html)

Et surtout,

[site francophone de vimistes](https://tuppervim.org/)


À propos des dispositions de clavier
------------------------------------

Connaître son clavier est important, surtout lorsque l’on passe du temps dessus.
Il existe pour cela la **méthode dactylo**, qui permet d’être encore plus à
l’aise.

Il existe également des “dispositions de clavier” alternatives (à azerty et
qwerty), pour différents usages, notamment :

- [Qwerty lafayette](https://qwerty-lafayette.org) qui permet à la fois d’avoir
  la très classique qwerty, et à la fois d’avoir une couche permettant une
  typographique francophone soignée, **et** les symboles de codes beaucoup plus
  accessibles,
- [Bépo](https://bepo.fr) qui est optimisée pour le français, a été normalisé
  par l’AFNOR pour être le clavier dactylo francophone de référence,
  malheureusement a mal vieilli en terme d’ergonomie, et est très peu pratique
  pour l’anglais,
- [Ergo-L](https://ergol.org) qui est naît de la fusion des deux précédents,
  qui est ergonomique à la fois pour le français, l’anglais, et le code, son
  seul défaut étant d’être peu répandu.



