33. Divers

Personne ne connait réellement ce qu'est la grammaire du shell Bourne. Même l'examen du code source est de peu d'aide.

-- Tom Duff

33.1. Shells et scripts interactifs et non interactifs

Un shell interactif lit les commandes à partir de l'entrée utilisateur sur un terminal tty. Entre autres choses, un tel script lit les fichiers de démarrage lors de l'activation, affiche une invite et active un contrôle de job par défaut. L'utilisateur peut interagir avec le shell.

Un shell exécutant un script est toujours un shell non interactif. Tout de même, le script peut toujours accéder au tty. Il est même possible d'émuler un shell interactif dans un script.

#!/bin/bash
MON_INVITE='$ '
while :
do
  echo -n "$MON_INVITE"
  read ligne
  eval "$ligne"
  done

exit 0

# Ce script d'exemple et la plupart des explications ci-dessus sont apportés
# par Stéphane Chazelas (encore merci).

Considérons un script interactif qui demande une saisie de l'utilisateur, habituellement avec des fonctions read (voir l'Exemple 14.3, « Affectation d'une variable, en utilisant read »). Dans la « vraie vie », c'est en fait un peu moins simple que ça. À partir de maintenant, on supposera qu'un script interactif est lié à un terminal tty, script appelé par un utilisateur à partir d'une console ou d'un xterm.

Des scripts d'initialisation et de démarrage sont nécessairement non interactifs car ils doivent fonctionner sans intervention humaine. Beaucoup de scripts administratifs et de maintenance système sont aussi non interactifs. Les tâches répétitives invariables nécessitent une automatisation par des scripts non interactifs.

Les scripts non interactifs peuvent fonctionner en arrière-plan alors que les interactifs sont suspendus attendant une saisie qui ne viendra jamais. Gérez cette difficulté en utilisant un script expect ou une entrée intégrée de type document en ligne vers un script interactif fonctionnant comme une tâche de fond. Dans le cas le plus simple, redirigez un fichier pour apporter l'entrée à la fonction read (read variable <fichier). Ces détournements particuliers rendent possible l'utilisation de scripts à usage général tournant en mode soit interactif soit non interactif.

Si un script a besoin de tester si, oui ou non, il est exécuté de manière interactive, il suffit simplement de savoir si la variable de l'invite, $PS1, est configurée (si le script attend une saisie de l'utilisateur, alors il a besoin d'afficher une invite).

if [ -z $PS1 ] # pas d'invite ?
then
  # non interactif
  ...
else
  # interactif
  ...
fi

Comme alternative, le script peut tester la présence de l'option « i » dans le drapeau $-.

case $- in
*i*)    # shell interactif
;;
*)      # shell non interactif
;;
# (D'après "UNIX F.A.Q.", 1993)
[Note]

Note

Il est possible de forcer un script à fonctionner en mode interactif avec l'option -i ou avec l'en-tête #!/bin/bash -i. Faites attention au fait que ceci peut entraîner un comportement étrange du script ou afficher des messages d'erreurs même si aucune erreur n'est présente.