Shell

La maitrise d'un shell Unix offre une puissante interface de contrôle des systèmes. Les shells permettent de rédiger à la volé des chaînes de commandes que votre expérience rendra de plus en plus complexe à mesure que vous découvrirez les options de chacunes d'elles. Avec le temps, la rédaction de script shell vous permettra de ne plus devoir exécuter manuellement des tâches ennuyeuses et répétitives.

Toutes la puissance et la simplicité de Linux réside dans l'utilisation conjointe d'une interface graphique efficace, c'est à dire adaptée à votre philosophie de travail et à vos goûts, et d'un shell maitrisé pour automatiser tout ce qui peux l'être.


Shell Script

Un script est un simple fichier texte contenant les commandes que vous auriez normalement saisi dans un terminal, séparées par des retour à la ligne. Une fois la suite de commande saisie, l'exécution du script se fait en demandant au shell de lire le fichier. Exemple :

bash mon_script.txt
bash mon_autre_script.sh
perl mon_super_script.pl
python mon_ultime_script.nimp

Sous Linux, l'extension d'un fichier n'a aucune incidence. Elles n'ont d'intérêt que pour le confort de l'utilisateur

Pour ne pas avoir à appeler sois-même l'interpréteur d'un script, dans un premier temps il faut rendre le fichier exécutable :

chmod +x mon_script.txt
chmod 755 mon_autre_script.sh

Puis, pour que le shell sache quel interpréteur de commande utiliser d'un script à l'autre, il faut ajouter sur la première ligne du script un chi-bang : #!

Ce marqueur permet d'indiquer quel binaire du système doit interpréter un script. Exemple :

#! /bin/bash
#! /bin/sh
#! /usr/bin/php

Face à la diversité des Unix qui ne choisissent pas toujours de mettre les binaires (fichier exécutable) aux mêmes endroits, il a été décidé de confier à la commande env la recherche des environnements d'exécutions. Cette commande est toujours placé dans /usr/bin/. Ainsi les scripts doivent désormais commencer par :

#! /usr/bin/env bash
#! /usr/bin/env sh
#! /usr/bin/env php

Avantage supplémentaire : il est possible dans certain cas d'indiquer une version d'environnement afin d'éviter les problèmes de dépréciation :

#! /usr/bin/env python3

Note: lancé seul dans un terminal, la commande env affichera l'ensemble des variables d'environnements.


Bash

Le Bourne Again SHell (bash) et le successeur du Bourne SHel (bsh). Il s'agit du shell majoritairement utilisé par les distributions Linux.

Il dispose d'un langage interprété permettant de déclarer des fonctions, des boucles, des variables, etc.

Affectation de variable

var=valeur

pas d'espace avant ou après le « = » !

Lecture de variable

echo $var

Ainsi :

Test

if test ; then instruction ; fi

if test ; then instruction ; else instruction ; fi

Boucle

for var in valeur1 valeur2 [...] valeurX ; do instruction ; done

while test ; do instruction ; done

etc... https://fr.wikipedia.org/wiki/Bourne-Again_shell

Exemple sur le client Ubuntu : vi /home/user/kikoo

#! /usr/bin/env bash
function readnum {
    # Lecture d'un nombre entier
    printf "Entrer un numéro entier svp [0-999]: "
    read -r num
    # Vérification que c'est un entier
    num=$(echo "$num" | grep -E '^[0-9]*$')
    # Relance si ce n'est pas un entier
    if [ -z "$num" ]; then
        printf "Tu dois entrer un entier b**let\n"
        readnum
    fi
}

# Appel de la fonction
readnum

# Evite une valeur trop grande
if [ "$num" -gt 99 ]; then

    # Evite une valeur vraiiiment trop grande
    if [ "$num" -gt 999 ]; then
        printf "Je vais me pendre... x_x\n"
        exit 2
    fi

    for i in $(seq 1 "$num"); do
        printf "b**let! "
    done

    printf "\n"

    exit 1
fi

# Affichage sequentiel
for i in $(seq 1 "$num"); do
    printf "%s kikoooo :o)\n" "$i"
    sleep 0.1
done

exit 0

Pour tester le script il faut en premier lieu lui donner le droit d'exécution :

chmod +x kikoo

Puis, pour exécuter un script local (qui n'est pas dans le PATH) il faut indiquer son adresse complète :

/home/$USER/kikoo

Pour éviter celà, si l'on se trouve dans le répertoire du script, il suffit d'utiliser l'alias « . » qui représente le répertoire courrant :

./kikoo

Alias de chemin

Sous Unix/Linux, des alias permettent de raccourcir les adresses :

Raccourcis clavier

Déplacement

Historique

Modification

Complétion

Divers

Pour en savoir plus

man -P 'less -p ^READLINE' bash
man -P 'less -p ^EDITING' readline

IFS

IFS (Internal Field Separator) est une variable d'environnement qui définie les caractères servant de séparateur d'argument. En général, l'IFS contient par défault les caractères espace, tabulation et nouvelle ligne. Vous pouvez le visualiser comme suis :

printf "%q\n" "$IFS"
$' \t\n'

Note : le marqueur %q de la fonction printf imprime l'argument associé avec les caractères spéciaux « échapé » de sorte qu'une chaîne soit réutilisable en entrée d'une autre commande...

Autrement dit, durant l'interprétation d'une commandes, le shell traitera ces caractères comme des marqueurs de séparation. Exemple :

mkdir test
touch 'un fichier' 'un autre fichier' 'un dernier fichier'
for i in $(ls *); do echo "Match: $i"; done
Match: un
Match: autre
Match: fichier
Match: un
Match: dernier
Match: fichier
Match: un
Match: fichier
IFS=$'\n'
for i in $(ls *); do echo "Match: $i"; done
Match: un autre fichier
Match: un dernier fichier
Match: un fichier

Manipuler l'IFS permet de grandement simplifier certain traitement :

for i in $PATH; do echo "Match: $i"; done
Match: /home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
IFS=':'
for i in $PATH; do echo "Match: $i"; done
Match: /home/user/bin
Match: /usr/local/sbin
Match: /usr/local/bin
Match: /usr/sbin
Match: /usr/bin
Match: /sbin
Match: /bin
var="a,b,c,d"
IFS=","
printf "%s\n" $var
a
b
c
d

Attention, le caractère « espace » est traité de façon spécial :

var="a-b---c-d"
IFS='-'
for i in $var; do echo -n "[$i]"; done; echo
[a][b][][][c][d]
var="a,b,,,c,d"
IFS=','
for i in $var; do echo -n "[$i]"; done; echo
[a][b][][][c][d]
var="a b   c d"
IFS=' '
for i in $var; do echo -n "[$i]"; done; echo
[a][b][c][d]
# Noter l'absence de [] vide. Contrairement aux autres caractères, les espaces sont agrégé.