Pourquoi / etc / profile n'est-il pas appelé pour les shells autres que les utilisateurs?

51

Shell de connexion et non-login défini comme:

su - $USER # will give you a login shell
bash # will give you a non-login shell

/ etc / profile n'est pas appelé pour les shells non connectés, comme lorsque vous démarrez konsole (kde). / etc / profile n'est appelé que pour les shells de connexion.

Pourquoi donc? S'il vous plaît expliquer, parce que j'aime comprendre la raison de cela.

James Mitch
la source

Réponses:

100

/etc/profile n’est invoqué que pour les shells de connexion, car c’est son objectif spécifique.

Si vous souhaitez qu'une commande s'exécute pour des shells interactifs qui ne sont pas des shells de connexion et que vous utilisez bash, insérez-la ~/.bashrcou /etc/bash.bashrc.

Le but des fichiers "profile" est de contenir des commandes devant être exécutées uniquement pour les shells de connexion. Ces fichiers sont:

  • /etc/profile, exécuté par tous les shells compatibles Bourne (y compris bashet dash) lorsqu'il est lancé en tant que shell de connexion.

  • Scripts dans /etc/profile.d.

    C'est pour les shells de type Bourne, mais ce n'est pas codé dans l'exécutable du shell lui-même. Plutôt, les commandes dans les /etc/profileappelle. Par exemple, sur mon système Ubuntu 12.04, /etc/profileinclut les lignes suivantes:

    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i
        fi
      done
      unset i
    fi
    
  • .profile dans le répertoire de base de l'utilisateur, exécuté par des shells compatibles Bourne lorsqu'il est lancé en tant que shell de connexion (sauf en cas de substitution, voir ci-dessous).

  • .bash_profileou .bash_logindans le répertoire personnel de l'utilisateur. Ceux-ci sont ignorés par les coquilles autres que bash. Mais si .bash_profileexiste, l' bashexécute au lieu de .profile . Si .bash_profilen'existe pas mais .bash_loginexiste, c'est exécuté à la place de .profile.

    (Mais il est courant que .bash_profileou .bash_login, lorsqu'il existe, être écrit de manière à * appeler explicitement .profile.)

    L'avantage des fichiers de profil spécifiques au shell est qu'ils peuvent contenir des commandes ou une syntaxe valables uniquement pour ce shell. Par exemple, je peux utiliser l' [[opérateur d'évaluation dans .bash_profile/ .bash_loginmais si je l'utilise .profilepuis dashme connecte avec mon shell, cela échouera.

Que faut-il entrer dans les fichiers "profile"?

Les fichiers "profile" doivent contenir des commandes qui ne doivent être exécutées qu'une seule fois, au début de la connexion. (Cela inclut les connexions graphiques, car elles commencent également par un shell de connexion.) Si un shell est interactif, l'utilisateur qui l'exécute est probablement connecté et a donc probablement un ancêtre (qui l'a démarré ou a démarré ce qui l'a démarré, ou commencé cela, etc.) qui était un shell de connexion.

Vous voudrez peut-être exécuter une commande une seule fois pour les raisons suivantes:

  1. il n'y a aucune raison de l'exécuter plus d'une fois par connexion, ce serait inefficace, ou
  2. cela produirait un résultat indésirable, à exécuter plus d'une fois par login.

Comme exemple de la deuxième situation, où un résultat indésirable pourrait se produire, considérons ces lignes, qui apparaissent par défaut dans chaque utilisateur ~/.profile:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Supposons que SSH ait démarré un autre shell (disons zsh), que vous vouliez revenir temporairement à bashvotre environnement bashtout en le conservant (afin de le réactiver zsh), puis que vous exécutiez un programme comme mccelui qui exécute un shell de son interface. S'il binexiste dans votre dossier personnel et que votre nom d'utilisateur est james, votre PATHshell le plus interne ressemble à quelque chose comme:

/home/james/bin:/home/james/bin:/home/james/bin:/home/james/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

C'est inefficace et (bien plus important encore), il est difficile de comprendre le contenu de PATH.

Ce n'est en aucun cas un désastre. Autant que je sache, si tous les fichiers de "profil" générés par un shell interactif, rien de grave ne se produirait, dans la configuration par défaut . Cependant, étant donné que les fichiers "profile" ont pour objectif de contenir des commandes à exécuter une seule fois par connexion , un utilisateur ou un administrateur peut ajouter des commandes à un profil qui ne doit être exécuté qu'au démarrage d'un shell de connexion.

Où placer les commandes pour chaque shell interactif à exécuter

Si vous utilisez bash, il existe des fichiers pour les commandes à exécuter dans chaque shell interactif:

  • /etc/bash.bashrc
  • .bashrc dans le répertoire personnel de l'utilisateur.

Ceci est le plus souvent utilisé pour les commandes qui

  1. affecter que l'environnement de la coquille dans laquelle ils s'exécutent - pas même les obus enfants, ou
  2. devrait fonctionner même quand ce n’est pas le shell de connexion.

Par exemple, la complétion par ligne de commande doit généralement être activée, qu’il s’agisse ou non bashdu shell de connexion. Cela apparaît donc dans ~/.bashrc:

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

Là, 1 et 2 s'appliquent tous les deux: cela ne se répercute pas sur les autres shell exécutés dans celui-ci, et la complétion par des tabulations devrait fonctionner bashmême si je me suis connecté avec un shell différent.

Où placer les commandes pour les shells de connexion et les shells interactifs autres que de login

Si vous utilisez bashet souhaitez une commande pour exécuter des shells de connexion et des shells interactifs et qui ne sont pas des shells de login, il suffit généralement de l'insérer /etc/bash.bashrcou de~/.bashrc . C'est parce que, par défaut, /etc/profileet les ~/.profileexécuter explicitement. Par exemple, ~/.profilea:

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

(De même, /etc/profilesources /etc/bash.bashrcpour bash.)

Ainsi, les fichiers "profile" et "rc" sont exécutés lorsque vous démarrez un bashshell interactif (qu’il s’agisse ou non d’un shell de connexion).

Où mettre des commandes pour s'exécuter dans des shells non interactifs

Vous ne souhaiterez probablement pas spécifier de commande à exécuter pour tous les shells non interactifs; ils seraient exécutés chaque fois qu'un script est exécuté (à condition que le script soit exécuté par le shell que vous configurez pour les exécuter).

Cela peut provoquer une casse importante. Si vous voulez le faire et qu'il n'y a pas de compte administrateur sur le système en plus de celui que vous utilisez, vous pouvez en créer un; cela peut faciliter la résolution des erreurs.

Dans bash, les fichiers "rc" sont réellement exécutés, que le shell soit interactif ou non . Cependant, au sommet, ils disent:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Ainsi, si vous avez besoin que les commandes s'exécutent automatiquement, même dans des shells non interactifs comme ceux exécutant des scripts, vous pouvez ajouter vos commandes avant ces lignes.

Démarrer un shell de connexion

La connexion démarre un shell de connexion. Si vous voulez qu'un shell démarré après cela se comporte comme un shell de connexion, démarrez-le avec le -ldrapeau (signifie l ogin ). Par exemple:

C'est la meilleure façon de lancer un shell de connexion (sans vous connecter) à moins que vous voulez commencer un comme un autre utilisateur. Ensuite, utilisez:

  • sudo -ifor root(à utiliser sudo -spour un shell root interactif sans connexion)
  • sudo -u username -i pour tout utilisateur
  • su - usernamepour les non- rootutilisateurs (à utiliser pour un shell root interactif sans connexion)su username

Qu'est-ce qu'un shell de connexion initial ?

Un shell de connexion initial est identique à un shell de connexion . Partout cette réponse dit "login shell", elle pourrait dire "shell de connexion initial" (sauf dans cette section, qui aurait déjà cessé de donner un sens).

L'une des raisons du terme shell de connexion initial est que le shell de connexion est également utilisé dans un sens différent - pour identifier le programme utilisé en tant que shell exécuté lors de la connexion. C'est le sens du shell de connexion utilisé pour dire:

  • " Le shell de connexion par défaut d' OpenBSD est ksh; dans Ubuntu, c'est bash."
  • "Vous pouvez changer votre shell de connexion avec chsh."

Lectures complémentaires

Eliah Kagan
la source
4
Une des meilleures réponses à toutes les questions de tous les sites Stack Exchange.
Mark E. Haase
1
> Les fichiers "profile" doivent contenir des commandes qui ne doivent être lancées qu’une fois, au début de la connexion. (Cela inclut les connexions graphiques, car elles commencent également par un shell de connexion.) Non non non non non! Cela ne veut absolument pas! Tous les shells de type bourne lisent uniquement .profile lors de sessions de shell de connexion interactives , c’est-à-dire celles qui ont démarré avec l’option -i ou celles connectées à un terminal de contrôle (qui ne sont pas vraies si le shell a été lancé par un gestionnaire d’affichage). La raison en est que le but de ce fichier est de configurer le terminal de l'utilisateur , pas seulement son environnement. Si un gestionnaire d'affichage tr
Eliah, j'ai reproduit le reste du commentaire de Derek ici, mais j'ai laissé la souche ci-dessus afin qu'il reçoive votre notification de réponse, bien qu'il ne puisse pas y répondre en raison d'exigences relatives à la réputation. Je lui ai cependant donné l'accès en écriture à la salle de discussion ci-dessus.
Seth
1
In bash, the "rc" files are actually run whether the shell is interactive or not. est incorrect. /etc/bash.bashrc est déclenché par /etc/bash.profile.
okwap
OKWAP est droite, les fichiers rc ne sont pas invoqués shell non-interactif, ce ceci est plus succinct et précis.
Nick Allen