Si vous avez trouvé cette page dans une recherche, vous essayez probablement de résoudre un problème lié au lancement de bash.
Peut-être que dans votre environnement, bash ne définit pas la variable d'environnement et vous ne comprenez pas pourquoi. Il se peut que vous ayez ajouté quelque chose dans divers fichiers de démarrage de bash ou dans les profils, ou dans tous les fichiers au hasard, jusqu'à ce que cela fonctionne.
Quoi qu'il en soit, le but de cette note est de présenter le processus de lancement de bash le plus simplement possible, afin que vous puissiez résoudre les problèmes.
Diagramme
Ce schéma résume tous les processus lors du lancement de bash.

Examinons maintenant chaque partie en détail.
Shell de connexion ?
Tout d'abord, vous devez choisir si vous êtes dans un shell de connexion ou non.
Un shell de connexion est le premier shell que vous atteignez lorsque vous vous connectez pour une session interactive. Un shell de connexion ne nécessite pas de saisie de nom d'utilisateur et de mot de passe. Vous pouvez forcer le lancement d'un shell de connexion en ajoutant le drapeau --login lors de l'appel bash, par exemple :
bash --login
Le shell de connexion configure l'environnement de base lors du premier lancement du shell bash.
Interactif ?
Ensuite, vous devez déterminer si le shell est interactif ou non.
Vous pouvez vérifier cela par la présence de la variable PS1 (elle définit la fonction d'entrée des commandes) :
if [ "${PS1-}" ]; then
echo interactive
else
echo non-interactive
fi Ou voir si le paramètre -i, avec une variable spéciale démarquée - dans bash, par exemple :
$ echo $-
S'il y a un caractère i, alors le shell est interactif.
Dans un shell de connexion ?
Si vous êtes dans un shell de connexion, alors bash recherche le fichier /etc/profile et le lance s'il existe.
Il recherche ensuite l'un de ces trois fichiers dans l'ordre suivant :
~/.bash_profile ~/.bash_login ~/.profile
Lorsqu'il en trouve un, il le lance et passe les autres.
Dans un shell interactif ?
Si vous êtes dans un shell interactif sans connexion (non-login shell), on suppose que vous avez déjà été dans un shell de connexion, que l'environnement est configuré et sera hérité.
Dans ce cas, les deux fichiers suivants sont exécutés dans cet ordre, s'ils existent :
/etc/bash.bashrc ~/.bashrc
Aucune option ?
Si vous n'êtes dans aucun shell de connexion ni dans un shell interactif, alors votre environnement sera effectivement vide. Cela crée beaucoup de confusion (voir ci-dessous sur les tâches cron).
Dans ce cas, bash regarde la variable BASH_ENV de votre environnement et crée le fichier correspondant qui y est spécifié.
Difficultés typiques et règles empiriques
Tâches cron
Dans 95 % des cas, le débogage d'un lancement bash est lié au fait que la tâche cron ne fonctionne pas comme prévu.
Cette tâche maudite fonctionne correctement lorsque je l'exécute dans la ligne de commande, mais échoue lors de son lancement dans crontab.
Ici deux raisons:
- Les tâches cron ne sont pas interactives.
- Contrairement aux scripts dans la ligne de commande, les tâches cron ne hériteront pas de l'environnement shell.
En général, vous ne remarquez pas ou ne vous souciez pas du fait que le script shell n'est pas interactif, car l'environnement est hérité de l'interface interactive. Cela signifie que tout PATH et alias est configuré comme vous vous y attendez.
C'est pourquoi il est souvent nécessaire de définir un PATH pour la tâche cron, comme ici :
* * * * * PATH=${PATH}:\/path\/to\/my\/program\/folder myprogramScripts appelant d'autres scripts
Un autre problème courant survient lorsqu'un script est configuré par erreur pour appeler un autre script. Par exemple, /etc/profile accesse à ~\/bashrc.
Cela se produit généralement quand quelqu'un essaie de corriger une erreur et que tout semble fonctionner. Malheureusement, lorsque vous devez séparer ces différents types de sessions, de nouveaux problèmes apparaissent.
Image Docker dans un bac à sable
Pour expérimenter l'exécution de l'interface shell, j'ai créé une image Docker qui peut être utilisée pour déboguer le lancement de l'interface shell dans un environnement sûr.
Lancement :
$ docker run -n bs -d imiell\/bash_startup
$ docker exec -ti bs bashLe Dockerfile se trouve .
Pour forcer la connexion et simuler une interface shell de connexion :
$ bash --login Pour vérifier l'ensemble des variables BASH_ENV:
$ env | grep BASH_ENV Pour le débogage crontab chaque minute exécutera un simple script (dans /root/ascript):
$ crontab -l
$ cat \/var\/log\/script.logSource : habr.com
