20 Aug 2022, 00:00

Notes sur shell (sh)

Share

Cet article se concentre sur les fonctionnalités des shells POSIX (notamment sh).

Debug

On peut mettre au début du script (ou en argument du shebang) ces directives :
set -x : toutes les commandes exécutées sont inscrites sur le terminal (standard error) avant leur exécution (avec un + en tête de ligne)
set -v : chaque ligne lue est inscrite sur le terminal (standard error)

Il me semble que ce sont des commandes “built-in” de bash ; toutefois cela semble fonctionner même si le shebang du script est /bin/sh.

Code de retour

Chaque commande/fonction exécutée renvoie un code de retour (exit code, ou encore code de retour), qui indique l’état de réussite de la commande.
C’est un entier de 0 à 255.

Généralement, 0 signifie un succès de l’opération, et tous les autres nombres un échec.

On peut définir le code de retour d’un script ou d’une fonction avec les commandes return et exit.

return & exit

return et exit servent tous 2 à interrompre l’exécution, et renvoient la valeur passée en argument (ou 0 à défaut d’argument ; et modulo 256 pour exit).
La différence entre les 2 est que return va interrompre la fonction mais rester dans le script, alors que exit va interrompre l’ensemble du script.

Récupérer la sortie d’une commande

Permet de stocker dans une variable la sortie d’une commande (standard output, et non le code de retour ; donc ce qui est affiché dans le terminal en cas d’exécution interactive). C’est la “substitution de commande”, que l’on fait avec la syntaxe
var=$(command)

On voit aussi
var=`command`
mais la première syntaxe est recommandée (notamment pour de l’imbrication de substitution, voir cette page ).

Si on récupère la sortie d’une fonction, cela contiendra la succession de toutes les sorties des commandes de la fonction.

Le retour $? d’une substitution correspond au retour de la commande/fonction, et non au retour de l’affectation de la variable.

Quelques symboles spéciaux

https://stackoverflow.com/questions/5163144/what-are-the-special-dollar-sign-shell-variables

$# : le nombre d’arguments
$1 : premier argument ; $2 : le 2e argument, etc…
$? : code renvoyé par la dernière commande executée ; renvoie 0 si aucune commande précédemment executée dans ce contexte (au sein d’un script, ou d’une session bash)
$@ : liste sous forme de vecteur de tous les paramètres : {$1, $2, $3 …}
$$ : PID du shell actuel
$IFS : séparateur de champ (actuel, car peut être changé)
$0 : nom de la commande ou du script shell

[ et test

En shell, [ est une commande ; c’est un alias de la commande test.
Celle-ci renverra vraie si la chaîne fournie est non-nulle, ou bien si l’affirmation qui suit est vraie.

[[ est une spécificité bash, et ne fonctionne pas en sh.

Arithmétique

bash possède des fonctions d’arithmétique avancées, mais ce n’est pas le cas de sh.
En shell POSIX, on peut utiliser la command expr. Par exemple :

a=1
a=$(expr $a + 1)
echo $a

qui donne 2.
Il faut bien penser à mettre les espaces autour du symbole +

Pour voir la liste des opérateurs : man expr
ou cette page.

Fonction

Déclaration :

myfunction () {
  echo $1
  echo $2
  return 0
}

À défaut de code de retour explicitement spécifié, la fonction retournera le retour de sa dernière commande exécutée.
Les paramètres de position ($1, $2 etc) sont ceux de l’appel de la fonction.

Utilisation :
myfunction 1 2 3

EN bash, on peut spécifier le mot clé “function” avant le nom de la fonction, mais ceci n’est pas reconnu en POSIX shell.

Portée

Il semble que les variables définies dans une fonction restent accessibles même après la sortie de la fonction (les variables sont par défaut globales).

Par exemple :

myfunction () {
  echo $a
  b=2
}

a=1
myfunction
echo $b

affichera “1 2”.

À l’inverse,

myfunction () {
  echo $a
  local b=2
}

a=1
myfunction
echo $b

affichera uniquement 1, la variable b étant définie localement.

if

Sous la forme
if [ blabla ]; then echo YES; fi
la condition if sera validée si test blabla renvoie 0. Par exemple blabla est une chaîne non-nulle ; ou encore blabla est une opération logique qui est vraie (par exemple 1 -eq 1, ou "abc" = "abc").

Sous la forme
if command ; then echo YES; fi
la condition sera validée si la commande/fonction “command” renvoie 0.
La commande “command” sera exécutée, et sa sortie affichée si applicable.