## Shell ### Les bases du shell
## Sommaire * Les commandes de base * Les redirections & fichiers spéciaux * Les commandes (suite) * Les Expressions régulières (Regex ou regexp) * Le script Bash

Les commandes de base

## Les basiques des basiques ```bash mv file1 file2 # Déplacer/renommer un fichier cp file1 copy1 # Copier un fichier rm file1 # Supprimer un fichier rmdir dossier1 # Supprimer un dossier vide rm -rf dossier1 # Supprimer un dossier et son contenu mkdir -p dossier/sub1/sub2 # Créer une arborescence de dossier touch monfichier # Crée un fichier vide ```
## [man](https://man7.org/linux/man-pages/man1/man.1.html) Doc et référence des commandes systèmes ```bash man man ``` `Entrée` pour faire défiler, `q` pour quitter Tips: marche aussi en recherche google Aussi, souvent il y a un -h ou --help
## [cat](https://man7.org/linux/man-pages/man1/cat.1.html) Concatène des fichiers vers l'output standard ```bash cat fichier1 fichier2 ```
## [ls](https://man7.org/linux/man-pages/man1/ls.1.html) Liste le contenu d'un répertoire (le courant par défaut) ```bash ls . ls ~ ```
## [ls](https://man7.org/linux/man-pages/man1/ls.1.html) Questions - Comment lister tous les fichiers d'un dossier en liste, du plus petit au plus gros, avec la taille lisible ? - Comment lister tous les fichiers d'un dossier en liste, du plus récent au plus vieux, avec la taille lisible ?
## [alias](https://man7.org/linux/man-pages/man1/alias.1p.html) Créer des alias de commandes (et les lister) ```bash alias alias my_ls="ls -larth" alias remote-ssh="ssh user@xxx.xxx.x.xx" ``` Tips : les alias peuvent être chargés automatiquement en les ajoutant dans `~/.bashrc` ou `~/.bash_aliases` (mieux)
## [alias](https://man7.org/linux/man-pages/man1/alias.1p.html) Questions - Que fait la commande `ll` ? - Créer un alias pour activer le VPN de AB
## [find](https://man7.org/linux/man-pages/man1/find.1.html) Rechercher des fichiers ou dossiers ```bash find . -type f # Liste les fichiers find / -type d # Liste les dossiers find ~ -name .bashrc # Trouve les fichiers/dossiers nommés .bashrc find . -type f -mtime -30 -name '*.py' # Liste les fichiers modifiés il y a moins de 30 jours ```
## [grep](https://man7.org/linux/man-pages/man1/grep.1.html) Recherche un pattern dans des fichiers ```bash grep error ./logs.txt # Cherche "error" dans le fichiers ./logs.txt grep -ri error -C5 ./log_folder # ? ```
## [head](https://man7.org/linux/man-pages/man1/head.1.html) ## [tail](https://man7.org/linux/man-pages/man1/tail.1.html) Affiche les premières/dernières lignes d'un fichier ```bash head -n 5 ./logs/my_long_log.txt tail -f ./logs/my_current_file.txt head -n -5 ./logs/my_long_log.txt # ? ```

Les redirections et fichiers spéciaux

## Entrée, sortie standard et sortie d'erreur En bash, il existe trois "descripteurs" particuliers ``` stdin => l'entrée (0) stdout => la sortie standard (1) stderr => la sortie d'erreur (2) ```
## la redirection de sortie >, >>, >& Indique au processus de rediriger la sortie standard vers un fichier ```bash echo "Hello" > message cat message echo "Hello2" >> message # ajoute à la fin cat message ```
## la redirection de sortie >, >>, >& Il est aussi possible de rediriger une sortie vers un autre descripteur en utilisant `X>&Y` ```bash echo "Erreur" 1>&2 # "Crée" une erreur mon_programme 2>&1 >> log.txt # Append tout dans le fichier log.txt ```
## le fichier "trou noir" `/dev/null` N'affiche rien si on l'affiche, efface tout ce qui est écrit dedans ```bash echo "Hello" >/dev/null cat /dev/null mon_programme >/dev/null 2>&1 # Plus de log ``` Tips: peut servir à faire disparaitre des logs trop verbeux d'une commande (pip par exemple)
## la redirection d'entrée Il est aussi possible de rediriger l'entrée depuis un fichier ```bash grep lo < message ```
## le pipe | Opérateur qui permet d'enchainer des commandes. Il relie la sortie standard vers l'input de la commande suivante ```bash ls -a | grep README.md ``` Tips: il existe aussi |& pour la sortie d'erreur
## le pipe | Question: - En utilisant `ls`, `tail`, et `wc`, compter le nombre de fichier dans le répertoire courant (. et .. exclus) - Que fait la commande ```bash cut -d ' ' -f 1 /var/log/apache2/access_logs | uniq -c | sort -n ``` Tips : https://explainshell.com/ peut aider à comprendre

Les commandes (la suite)

## xargs Permet de construire et executer des lignes de commandes ``` ls -a | xargs cat ls -a | grep ".txt$" | xargs -n1 -I {} echo mv {} bazire/{}| sh ```
## awk Langage de "scanning" et de "processing" ``` bash cat - > marks.txt << EOF 1) Amit Physics 80 2) Rahul Maths 90 3) Shyam Biology 87 4) Kedar English 85 5) Hari History 89 EOF awk '{print $3 "\t" $4}' marks.txt awk '/a/ {print $0}' marks.txt awk '/a/ {print $4 "\t" $3}' marks.txt awk '/a/{++cnt} END {print "Count = ", cnt}' marks.txt awk 'length($0) > 18' marks.txt ```
## sed Editeur de flux (permet de transformer l'input d'une pipeline de commande entre deux commandes). "En gros", il permet d'appliquer une regex à un input. ```bash echo "Bonjour toto" | sed -e "s/toto/$(id -un)/" echo "help: ## Display commands help" | sed -e 's/^\(.*\):.* ## \(.*\)/\\\\033[36m\1\\\\033[0m \2/g' | xargs echo -e ```

Les expressions régulières

## C'est quoi une Regex ? Il s'agit d'une syntaxe permettant de reconnaître un ensemble de mots répondant aux contraintes Cela permet de chercher de manière efficace et de modifier ses expressions Utilisation : via sed, dans l'éditeur de code, dans les langages
## La grammaire ``` r"abc" => matchera n'importe quelle chaine de caractères contenant abc (dont abc) r"[a-z]{10}" => matchera n'importe quelle chaine de caractères contenant 10 lettres minuscules r"[a-zA-Z0-9]{10}" => matchera n'importe quelle chaine de caractères contenant 10 lettres ou chiffres r"^abc" => matchera n'importe quelle chaine de caractères commençant par 'abc' r"abc$" => matchera n'importe quelle chaine de caractères terminant par 'abc' r"^abc$" => matchera exactement 'abc' r"^.$" => matchera toute chaine de un caractère r".*" => matchera toutes les chaines, y compris la chaine vide r".+" => matchera toutes les chaines d'au moins un caractère ```
## La grammaire (suite) ``` () # Groupe capturant x? # Optionnel (?=foo) # Lookahead (?!foo) # Negative Lookahead ```
## Questions ``` r"^[a-c]{1,10}$" => ? r"^abc?$" => ? r"^a[bc0-9]*d?$" => ? ``` Tips : - https://regex101.com/ - https://www.regexplanet.com/advanced/python/index.html
## Exercice - Copier le premier paragraphe de https://www.lipsum.com/ - Ecrire une régex qui matche tous les mots en majuscules - Puis, remplacer le mot par la première lettre de ce mot

Script bash

## Le shebang Donne un lien vers l'interpréteur (quand on lance le fichier en `./monfichier`) ```bash #!/bin/sh #!/bin/bash #!/usr/bin/env python3 ```
## Les variables ```bash #!/bin/bash # Simple variable STR="Hello World!" echo $STR # Can contain output of commande OF=/var/my-backup-$(date +%Y%m%d).tgz echo $OF # Also, we got list allThreads=(1 2 4 8 16 32 64 128) # We can iterate on values for t in ${allThreads[@]}; do echo $t done # or on index for i in ${!allThreads[@]}; do echo $i ${allThreads[$i]} done # You can even have mapping (associative array) declare -A myAssociativeArray myAssociativeArray[a]=123 myAssociativeArray[b]=456 myAssociativeArray+=([c]=789 [d]=012) echo ${myAssociativeArray[*]} for i in ${!myAssociativeArray[@]}; do echo $i ${myAssociativeArray[$i]} done ```
## Les arguments $1, $2, ..., ${10} Donne un lien vers l'interpréteur (quand on lance le fichier en `./monfichier`) ```bash #!/bin/bash echo "Mon script est : $0" echo "Ou ${BASH_SOURCE[0]}" echo "Tous mes arguments : $*" echo "Le nombre d'arguments : $#" echo "Pour itérer : $@" echo "Le 1er paramètre est : $1" echo "Code de retour de la dernière commande : $?" ```
## Exercice Ecrire un script qui - prend en entrée un fichier - vérifie si ce fichier existe - affiche et retourne une erreur si il n'existe pas - sinon, compte et affiche le nombre d'occurences de l'argument 2
## Exercice Ecrire un script qui - prend en entrée un dossier - liste et affiche les fichiers CSV - V1 : pour chaque fichier CSV du dossier, extraire la première colonne et l'exporter dans un fichier suffixé par _col1.csv - V2 : pour chaque fichier CSV du dossier, extraire les colonnes données en arguments et l'exporter dans un fichier suffixé par _${col}.csv
## Ressources - [`set -euo pipefail`](https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca) - https://linuxconfig.org/bash-script-display-usage-and-check-user - https://www.shellcheck.net/# - https://regex101.com/ - https://www.regexplanet.com/advanced/python/index.html - https://explainshell.com - https://man7.org/linux/man-pages/index.html