Outils pour utilisateurs

Outils du site


workshop_shell

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
workshop_shell [2023/11/03 16:42] – créée bigMaxworkshop_shell [2024/03/20 12:56] (Version actuelle) bigMax
Ligne 1: Ligne 1:
 <markdown> <markdown>
  
-# Workshop Shell Unix+# Workshop Shell Unix compatible (Interpréteur de commandes)
  
-Ne prennez pas de notes => Testez sur votre machine+## Guidelines pour l'atelier 
 +*Deconseiler de prendre des notes le workshop est disponible sur le wiki.* 
 +- *Proposer d'interrompre et poser des questions à chaud.* 
 +- *Demander à l'assemblé ce que va produire une ligne commande avant de l'exécuter.*
  
 ## Intro: shell / terminal ## Intro: shell / terminal
 +On désigne souvent le shell par :
 +- le terminal
 +- la console
 +- le shell
 +- le bash
  
-## Navigation : pwd ; cd ; ls+Le shell Unix est une Interface en Ligne de Commande (CLI) qui permet à un utilisateur d’interagir avec un système d'exploitation Unix en entrant du texte. Le premier shell Unix date de 1971, et depuis, plusieurs sont nés avec chacun ses subtilités, ses avantages, et ses préférences. Dans les grandes lignes, tous les shell Unix se ressemblent. Dans la suite de cet article nous le désignerons simplement le shell.
  
-## Fichiers : cp ; mv ; rm ; mkdir+### Exemples de shell 
 +- sh (Bourne shell) le plus répendu 
 +- bash (Bourn again shell) le plus populaire ? 
 +- zsh le plus geek ? 
 +- ksh (Korn shell) 
 +- ...
  
-## Commandes : help ; man+### Présentation d'une ligne de commande 
 +**COMMANDE**   **[ESPACE]**   **ARGUMENT_1**   **[ESPACE]**   **ARGUMENT_2**   **[ESPACE]**  ...  **ARGUMENT_N**
  
-## IO (Entrées Sorties: redirection / pipelines+Retourne un "Result Code" (RCcompris entre 0 et 127. 
 +- RC = 0 indique que tout s'est bien déroulé. 
 +- RC > 0 indique qu'une erreur s'est produite.
  
-## Expansion : * ~ {1..5} {Z..A} $USER +## Navigation dans un FS (système de fichiers) pwd ; cd ; ls 
-Attention les expansions dependent beaucoup du shell (sh, bash, zsh, ...) +*Présentation avec GUI ouvert.* 
 +- pwd: print working directory 
 +- cd: change directory 
 +- ls: list
  
-## Permissions : ls -l ; chmod ; chown+``` bash 
 +pwd 
 +cd /tmp 
 +pwd 
 +cd 
 +pwd 
 +cd - 
 +pwd 
 +cd 
 +cd ~ 
 +pwd 
 +ls 
 +ls -
 +```
  
-## Variables $PS1 $PATH+## Manipulation des fichiers touch ; cp ; mv ; rm ; mkdir 
 +*Présentation avec GUI ouvert.* 
 +- touch: touche un fichier (le créé si il n'existe pas, update son timestamp de modification) 
 +- cp: copy files 
 +- mv: move files 
 +- rm: remove files 
 +- mkdir: make directory 
 + 
 +``` bash 
 +touch foo 
 +cp foo bar 
 +mv bar baz 
 +rm foo 
 +mkdir pif 
 +mkdir -p paf/pouf 
 + 
 +``` 
 + 
 +## Permissions des fichiers : ls -l ; chmod ; chown 
 +- chmod: change file mode 
 +- chown: change file owner 
 +``` bash 
 +ls -l foo 
 +chmod u-r foo 
 +ls -l foo 
 +sudo chown root:root foo 
 +ls -l 
 +``` 
 + 
 +## Obtenir de l'aide : man ; help 
 +La commande man permet d'obtenir de l'aide sur les programmes installés. **On peut rechercher le mot clé "foo" dans le manuel en tappant "/foo".** 
 + 
 +``` bash 
 +man man 
 +``` 
 + 
 +L'aide des commandes internes au shell n'est pas disponible dans le manuel man. La commande help permet d'obtenir une aide sommaire sur les commandes du shell. 
 +Cette commande n'est pas disponible dans tous les shell : sur zsh elle est remplacée par run-help. 
 +``` bash 
 +help 
 +help cd 
 +```
  
 ## Administration : ps ; top ; du ; df ; free ; mount ## Administration : ps ; top ; du ; df ; free ; mount
 +- id: display user id
 +- last: display last logged in users
 +- ps:  list process
 +- top: display top process
 +- du: disk usage
 +- df: disk free
 +- free: display RAM infos
 +- mount: display mounted file systems
 +``` bash
 +id
 +last
 +ps u
 +ps aux
 +uptime
 +top
 +du -h
 +df -h
 +free -h
 +mount
 +```
  
-## Scripts : philosophie tests loops fonctions+## Quelques autres commandes basiques 
 +- echo: imprime les arguments sur la sortie standard (l'écran) 
 +- cat: concatene des fichiers et les imprime sur la sortie standard (l'écran) 
 +- read: lit l'entrée standard (le clavier) et stoque le contenu dans une variable 
 +- which: localise le chemin absolu d'une commande 
 +- grep: imprime les lignes d'un fichier qui match un pattern 
 +- cut: extrait des colonnes d'un fichier 
 +- paste: fusionne des lignes d'un ichier 
 + 
 +## Historique des commandes 
 +``` bash 
 +history 
 +``` 
 +On peut utiliser les fleches haut et bas du clavier pour parcourir l'historique des commandes que l'on a entrées. 
 + 
 +**Avec la combinaison de touch [CTRL]-[R] on peut rechercher dans l'historique et ça ça change la vie.** 
 + 
 +Avec la variable d'envrionnement **HISTCONTROL=ignoreboth** (en général configurée par défaut) si on ne souhaite pas qu'une commande apparaissent dans l'historique, on peut la préfixer par un **[ESPACE]**. 
 +``` bash 
 +echo "$HISTCONTROL" 
 +HISTCONTROL=ignoreboth 
 +echo "message public" 
 + echo "message secret" 
 +echo "message public 2" 
 +history 10 
 +``` 
 + 
 +Généralement la commande history à des options pour allez supprimer des entrées dans l'historique. 
 +``` bash 
 +help history 
 +echo "mon secret" 
 +history 5 
 +history -d -3 
 +history 5 
 +``` 
 + 
 +## Expansion : * ? ~ {1..5} {Z..A} 
 +Attention les expansions dependent beaucoup du shell (sh, bash, zsh, ...)  
 +L'expansion des arguments a lieu avant d'executer la commande. 
 + 
 +``` bash 
 +rm -rf work1 ; mkdir work1 ; cd work1 
 +touch foo bar baz 
 +ls f* 
 +ls b* 
 +ls b?z 
 +echo {A..C} 
 +``` 
 + 
 +## IO (Entrées Sorties) (redirection / pipelines) : 2>  >  >>  |  << 
 + 
 +### Configuration par défaut de STDIN STDOUT et STDERR 
 +Tous les programmes : 
 +- lisent leur entrée sur le canal STDIN (entrée standard)  
 +- écrivent sur le canal STDOUT (sortie standard) 
 +- informe des érreurs sur le canal STDERR (sortie d'erreur) 
 + 
 +Par défaut : 
 +- STDIN est relié au "clavier" 
 +- STDOUT et STDERR sont reliés à "l'écran" (difficile à distinguer) 
 + 
 +</markdown> 
 +{{ ::shell_program_ios.png?direct&400 |}} 
 +<markdown> 
 + 
 +### Suppression des erreurs : 2> /dev/null 
 +``` bash 
 +rm bar ; echo $? 
 +rm bar 2> /dev/null ; echo $? 
 +``` 
 + 
 +### Ecriture dans fichier : > 
 +``` bash 
 +rm -rf work2 ; mkdir work2 ; cd work2 
 +echo "Hello World" > foo 
 +cat foo 
 +> foo 
 +cat foo 
 +``` 
 + 
 +### Ecrire à la fin d'un fichier : >> 
 +``` bash 
 +> bar 
 +echo hello > bar 
 +cat bar 
 +echo world >> bar 
 +cat bar 
 +``` 
 + 
 +### Lire un fichier sur l' entrée standard : < 
 +Lecture de l'entrée depuis un fichier. 
 +``` bash 
 +read txt ; echo "$txt" 
 +echo "Hello world !" > foo 
 +read txt < foo ; echo "$txt" 
 +``` 
 + 
 +### Ne pas interrompre la lecture de l'entrée standard avec [ENTER] : << EOF 
 +``` bash 
 +cat << EOF 
 +foo 
 +bar 
 +baz 
 +EOF 
 +``` 
 + 
 +### Ecrire sur la sortie d'erreur : >&
 +``` bash 
 +echo "sur la sortie standard" 
 +>&2 echo "sur la sortie d'erreur" 
 +``` 
 + 
 +### Rediriger les sorties : > 2> 2>&
 +``` bash 
 +echo "pif" > stdout 
 +>&2 echo "paf" 2> stderr 
 +>&2 echo "pouf" > stdout 2>&
 +``` 
 + 
 +### Pipeline (chaîner des programmes) : | 
 +"Pipeliner" 2 programmes permet d'enchainer l'exécution des 2 programmes. La sortie standard (STDOUT) du premier programme (à gauche) sera "streamée" dans l'entrée standard (STDIN) du second programme. 
 + 
 +``` bash 
 +cat bar | grep "lo" 
 +``` 
 + 
 +</markdown> 
 +{{ ::piped_programs_ios.jpeg?direct&400 |}} 
 +<markdown> 
 + 
 +## Logique : ; && || ! 
 +``` bash 
 +echo "un" ; echo "deux" 
 +echo "OR_1" || echo "OR_2" 
 +echo "AND_1" && echo "AND_2" 
 +false ; echo "RC=$?" 
 +! false ; echo "RC=$?" 
 +true || echo "second statement" ; echo "RC=$?" 
 +false || echo "second statement" ; echo "RC=$?" 
 +true && echo "second statement" ; echo "RC=$?" 
 +false && echo "second statement" ; echo "RC=$?" 
 +``` 
 + 
 +## Interpretation des variables : $USER $PATH $PS1 $? 
 +``` bash 
 +echo $PATH 
 +echo $HOME 
 +echo $USER 
 +echo "$USER" 
 +echo '$USER' 
 +echo '"$USER"' 
 +echo "'$USER'" 
 +echo "$USERfoo 
 +echo "${USER}foo 
 +echo ${USER^^} 
 +TOUT_EN_MAJ="FOOBARBAZ" ; echo "${TOUT_EN_MAJ,,}" 
 +export 
 +echo $PS1 
 +echo $? 
 +echo $! 
 +``` 
 +Il existe une priorité entre simple et double quotte. Une variable ne sera jamais interprété entre simple quottes sauf si englobé entre double quottes. 
 + 
 +## Bloc de commandes : { cmd1 ; cmd2 ; ... ; cmdN ; }  ( cmd1 ; cmd2 ; ... ; cmdN ) 
 +- Le bloc () est exécuté dans un sous processus. 
 +- Le bloc {} doit se terminer par un ; 
 +``` bash 
 +false || ( echo foo ; echo bar ; var=baz ) ; echo $var 
 +false || { echo foo ; echo bar ; var=baz ; } ; echo $var 
 +``` 
 + 
 +## Un peu de recul : execution des commandes 
 +On peut exécuter les commandes intégrés au shell ou les programmes executables. 
 +``` bash 
 +which cd ; echo $? 
 +which pwd ; echo $? 
 +ls -l /usr/bin/pwd 
 +``` 
 + 
 +Pour exécuter un programme il faut qu'il soit exécutable puis il faut tapper son nom dans l'invite de commande suivi de entrer. 
 +``` bash 
 +/usr/bin/ls 
 +ls 
 +echo $PATH 
 +PATH="/tmp" 
 +ls 
 +which ls 
 +/usr/bin/ls 
 +cd /usr/bin 
 +ls 
 +./ls 
 + 
 +``` 
 + 
 +## Scripts : philosophie tests loops fonctions arguments
  
 ### Philosophie UNIX ### Philosophie UNIX
Ligne 31: Ligne 318:
 - Écrivez des programmes pour gérer des flux de texte [en pratique des flux d'octets], car c'est une interface universelle. - Écrivez des programmes pour gérer des flux de texte [en pratique des flux d'octets], car c'est une interface universelle.
  
 +### Fil rouge : un script pour trier et compresser ses photos
 +- shebang
 +- fonctions
 +- return code (exit)
 +- arguments
 +- variables
 +- conditions
 +- boucles
 +
 +Pour installer les packages nécéssaires sur debian/ubuntu like :
 +``` bash
 +sudo apt install imagemagick exiftool
 +```
 +
 +### Initialisation du script : shebang usage()
 +- Nous éditons un nouveau fichier texte que nous allons "transformer" en script.
 +- Première ligne du script : le shebang, qui indique à notre interpreteur que ce fichier est un script et quel interpreteur utiliser pour executer le script.
 +- Définition d'une fonction **usage()** pour guider l'utilisateur, et documenter l'utilisation du script.
 +
 +``` bash
 +vim gere_mes_photos.sh
 +
 +#! /bin/bash
 +
 +usage() {
 +        >&2 echo "Message: $1"
 +        >&2 echo "usage: $0 [PHOTO_1] ... [PHOTO_N]"
 +        exit 1
 +}
 +
 +>&2 echo "Lancement de mon outil de gestion des photos ..."
 +
 +./gere_mes_photos.sh
 +chmod u+x gere_mes_photos.sh
 +./gere_mes_photos.sh
 +```
 +
 +### Tester les arguments en entrée : test
 +Un programme prend en paramètre des arguments séparés par des espaces (par défaut).
 +
 +On vérifie que l'utilisateur nous fournit au moins un argument.
 +On enrobe la variable $1 de double quottes ("") pour éviter les bugs lorsque la variable contient un espace par exemple.
 +``` bash
 +test -n "$1" || usage "No picture supplied as argument !"
 +test -n "$@" || usage "No picture supplied as argument !"
 +
 +./gere_mes_photos.sh
 +
 +./gere_mes_photos.sh foo
 +```
 +
 +### Traiter chaque fichier fournit en entrée : for do done ; while do done ; les variables
 +On utilise une boucle pour parser tous les arguments un par un.
 +``` bash
 +for file in "$@"; do
 +        >&2 echo "Traitement du fichier: '$file' ..."        
 +done
 +```
 +
 +### Utiliser un bloc conditionnel : if then elif else
 +On peut utiliser un bloc conditionnel pour effectuer un traitement.
 +``` bash
 +        if ! [ -f "$file" ]; then
 +                usage "Supplied file: [$file] is not a valid file !"
 +        fi
 +        
 +./gere_mes_photos.sh foo bar
 +```
 +
 +### Executer nos 2 programmes sur chaque fichier
 +- On utilise le programme exiftool pour renommer notre image en utilisant la metadata "date de création" incluse dans notre fichier.
 +- On utilise le programme convert pour resize notre image.
 +
 +``` bash
 +tmpFile="compressed.${file}"
 +>&2 echo "Compression du fichier [$file] > [$tmpFile] ..."
 +convert -resize 50% "$file" "$tmpFile"
 +
 +>&2 echo "Renommage du fichier [$file] ..."
 +exiftool '-Filename<CreateDate' -d '%Y-%m-%d-%H_%M_%S%%-c.%%e' "$tmpFile"
 +rm -- "$tmpFile"
 +```
 +
 +### Script complet
 +``` bash
 +#! /bin/sh
 +
 +usage() {
 +        >&2 echo "$1"
 +        >&2 echo "usage: $0 <PHOTO_1> [PHOTO_2] ... [PHOTO_N]"
 +        exit 1
 +}
 +
 +test -n "$1" || usage "No picture supplied as argument !"
 +
 +for file in "$@"; do
 +        >&2 echo "Processing $file ..."
 +
 +        if ! [ -f "$file" ]; then
 +                usage "Supplied file: [$file] is not a valid file !"
 +        fi
 +
 +        tmpFile="compressed.${file}"
 +        >&2 echo "Compression du fichier [$file] > [$tmpFile] ..."
 +        convert -resize 50% "$file" "$tmpFile"
 +
 +        >&2 echo "Renommage du fichier [$file] ..."
 +        exiftool '-Filename<CreateDate' -d '%Y-%m-%d-%H_%M_%S%%-c.%%e' "$tmpFile"
 +        rm -- "$tmpFile"
 +done
 +```
 +
 +## Retours
 +- Si focus sur les scripts, ne pas présenter les trucs non nécéssaires pour les scripts
 +  - permissions ?
 +  - admin ?
 +  - files ?
  
 +- tldr comme manuel express ?
  
 </markdown> </markdown>
workshop_shell.1699029778.txt.gz · Dernière modification : 2023/11/03 16:42 de bigMax