Exile on Keyboard St. - Blog sur Linux et Debian

Aller au contenu | Aller au menu | Aller à la recherche

samedi 18 avril 2015

Bien spécifier l'interpréteur de vos scripts Shell avec le Shebang

Considérons un script Shell très simple:

# script.sh

echo "Running script $0 with $SHELL"

Lors de son exécution en lançant ./script.sh, j'obtiens:

Running script ./script.sh with /bin/bash

Le script a été lançé avec l'interpréteur bash puisqu'il s'agit du Shell défini pour mon utilisateur.

Si maintenant, j'ajoute la ligne suivante au tout début de mon script:

#!/bin/ksh

J'obtiens à l'éxécution le message suivant:

bash: ./script.sh : /bin/ksh : mauvais interpréteur: Aucun fichier ou dossier de ce type

Pourquoi ? J'ai demandé au Shell bash, qui est mon Shell courant, de lancer le script avec le Korn Shell (/bin/ksh) qui n'est pas installé sur ma machine, et j'ai donc un message d'erreur.

Cette première ligne ajoutée s'appelle un "Shebang" et permet donc de changer d'interpréteur de commande localement dans un script. Le Shebang se compose donc des caractères "dièse" puis "point d'exclamation" suivis du chemin d'accès à l'interpréteur de commandes.

Notez que ce chemin doit être complet, ce qui est peut être gênant si nos scripts Shell doivent fonctionner sur des machines avec des Shells installés ailleurs que dans /bin. Même si c'est rare, cela peut arriver.

Maintenant, laissons tomber ksh puisqu'il n'est pas installé et considérons que notre script doit être exécuté avec bash.

Il y a un moyen de s'affranchir de ce chemin complet de l'interpréteur: il faut utiliser la commande env qui va utiliser la variable d'environnement PATH pour trouver le chemin de bash. On change donc le script comme suit:

#!/usr/bin/env bash
# script.sh

echo "Running script $0 with $SHELL"

L'interpréteur est bien trouvé parce que par défaut, le chemin /bin se trouve dans le PATH.

samedi 8 mars 2014

Quels scripts d'initialisation utiliser sous Debian: .bash_profile ou .bashrc ?

Quand on définit des alias ou qu'on modifie le PATH sous Linux, la question de savoir dans quels scripts d'initialisation du Shell on le fait se pose souvent.

Faut t-il définir les alias dans le fichier .bash_profile de l'utilisateur ou dans le fichier .bashrc ?

Avant de répondre à cette question, il faut savoir qu'il y a deux types de Shell: les Shell de connexion (ou de login) et les autres.

Le Shell de connexion est celui qui est invoqué lorsqu'on se connecte sur la console:

  • lors de la connexion physique à une machine dépourvue d'environnement graphique,
  • ou en utilisant les raccourcis Ctrl-Alt F1, Ctrl-Alt F2 ...,
  • ou lors d'une connexion à une machine distante via ssh

et aussi si on utilise la commande bash --login.

Tous les autres Shells lançés par un Shell de connexion n'en sont donc pas. Les Anglais parlent de "non-login Shell".

Donc pour revenir aux scripts d'initialisation du Shell du répertoire courant de l'utilisateur:

  • .bash_profile est le script d'initialisation des Shells de login,
  • .bashrc est le script d'initialisation des autres Shell,

Selon l'usage des alias que l'on veut faire, on les définira dans un fichier ou dans un autre.

Mais un alias définit dans .bash_profile ne sera pas visible par un Shell lancé depuis l'environnement graphique puisque le Shell utilisé dans ce cas n'est pas un Shell de login.

Par contre sous Debian les définitions d'alias faites dans .bashrc seront utilisables non seulement dans un "non-login Shell" puisqu'ils sont définis dans le script d'initialisation de ceux-cis mais aussi par les Shells de login puisque sous Debian généralement .bashrc est appelé par .bash_profile comme suit:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

Par conséquent, la façon la plus simple de définir des alias, le PATH ou de faire d'autres réglages sous Debian consiste à le faire dans le fichier .bashrc. Sur d'autres distributions Linux, cela reste évidemment vrai tant que l'on source .bashrc depuis .bash_profile.

Enfin, il faut savoir que si le fichier .bash_profile n'existe pas alors c'est le fichier .profile qui sera recherché.