65 votes

Pourquoi /etc/profile n'est pas invoqué pour les shells non-login ?

Login et non-login Shell définis comme :

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

/etc/profile n'est pas invoqué pour les shells non-login, comme lorsque vous démarrez konsole (kde). Le fichier /etc/profile n'est invoqué que pour les shells de connexion.

Pourquoi ? Expliquez-moi, car j'aimerais en comprendre le raisonnement.

126voto

Eliah Kagan Points 111731

/etc/profile est invoqué uniquement pour les shells de connexion car c'est son but spécifique.

Si vous souhaitez qu'une commande soit exécutée pour les shells interactifs qui sont pas et vous utilisez bash et le mettre dans ~/.bashrc o /etc/bash.bashrc .

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

  • /etc/profile , géré par tous shells compatibles avec Bourne (y compris bash y dash ) lorsqu'il est lancé en tant que login Shell.

  • scripts en /etc/profile.d .

    C'est pour les shells de style Bourne, mais ce n'est pas codé dans l'exécutable Shell lui-même. Plutôt, les commandes dans /etc/profile les appelle. Par exemple, sur mon système Ubuntu 12.04, /etc/profile comprend ces lignes :

    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 personnel de l'utilisateur, exécuté par les shells compatibles Bourne lorsqu'ils sont lancés en tant que login Shell (à moins d'être surchargé, voir ci-dessous).

  • .bash_profile o .bash_login dans le répertoire personnel de l'utilisateur. Ils sont ignorés par les shells autres que bash . Mais si .bash_profile existe, bash l'exécute 代わりに .profile . Si .bash_profile n'existe pas mais .bash_login existe, qui est exécuté à la place de .profile .

    (Mais il est courant que .bash_profile o .bash_login lorsqu'elle existe, doit être rédigée de manière à *appeler explicitement .profile .)

    L'avantage des Shell spécifiques. profil est qu'ils peuvent contenir des commandes ou une syntaxe qui ne sont valables que pour ce Shell. Par exemple, je peux utiliser le fichier [[ opérateur d'évaluation dans .bash_profile / .bash_login mais si je l'utilise dans .profile puis connectez-vous avec dash comme mon Shell, il échouera.

Qu'est-ce qui devrait aller dans les fichiers "profil" ?

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

Vous pouvez vouloir exécuter une commande une seule fois parce que :

  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, de l'exécuter plus d'une fois par connexion.

À titre d'exemple de la deuxième situation, où un résultat indésirable se produirait, considérons ces lignes, qui apparaissent par défaut dans la page d'accueil de 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 vous vous connectiez en SSH, exécutez un autre Shell (disons, zsh ), à un moment donné, vous avez voulu revenir temporairement à bash mais conservez votre environnement (ainsi couru bash encore une fois pendant zsh ), puis exécute un programme comme mc qui exécute un Shell dans le cadre de son interface. Si bin existe dans votre dossier personnel et votre nom d'utilisateur est james , votre PATH dans le Shell le plus interne est 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 (beaucoup plus important) cela rend difficile la compréhension du contenu de l'application PATH .

Ce n'est pas du tout un désastre, cependant. Pour autant que je puisse dire, si chaque Shell interactif s'approvisionnait en fichiers "profil", rien de terrible ne se produirait, dans la configuration par défaut . Cependant, étant donné que le but des fichiers "profil" est de contenir des commandes à exécuter une seule fois par connexion. un utilisateur ou un administrateur peut ajouter des commandes à un profil qui doit s'exécute uniquement lors du 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 qui doivent être exécutées 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. n'affectent que l'environnement du Shell dans lequel ils sont exécutés - pas même les shells enfants, ou
  2. devrait s'exécuter même si ce n'est pas le login Shell.

Par exemple, la complétion de la ligne de commande par des tabulations doit généralement être activée, qu'il s'agisse ou non de bash était le login Shell. Ainsi, ceci apparaît dans ~/.bashrc :

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

Voilà, 1 y 2 les deux s'appliquent : cela ne s'applique pas aux autres shells exécutés à l'intérieur de celui-ci, et la complétion par tabulation devrait fonctionner en bash même si je me suis connecté avec un Shell différent.

Où placer les commandes pour les shells de connexion et les shells interactifs sans connexion ?

Si vous utilisez bash et voulez une commande à exécuter dans les shells de connexion et les shells interactifs et qui ne sont pas des shells de connexion, il suffit généralement de le mettre dans /etc/bash.bashrc o ~/.bashrc . Cela est dû au fait que, par défaut, /etc/profile y ~/.profile les exécuter explicitement. Par exemple, ~/.profile a :

# 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/profile sources /etc/bash.bashrc para bash .)

Ainsi, les fichiers "profile" et "rc" sont tous deux exécutés lorsque vous lancez un programme interactif. bash Shell (qu'il s'agisse ou non d'un Shell de connexion).

Où placer les commandes à exécuter dans les shells non interactifs ?

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

Cela peut provoquer des ruptures importantes. Si vous faites cela et qu'il n'y a pas d'autre compte d'administrateur sur le système que celui que vous utilisez, vous pouvez en créer un ; cela peut faciliter la correction des erreurs.

Sur bash les fichiers "rc" sont effectivement exécutés si le Shell est 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 les shells non interactifs comme ceux qui s'exécutent pour exécuter les scripts, vous pouvez ajouter vos commandes. antes de ces lignes.

Démarrage d'une connexion Shell

L'ouverture de session démarre un Shell. Si vous voulez qu'une Shell démarrée après cela se comporte comme une Shell de connexion, démarrez-la avec la commande -l (signifie l ogin ). Par exemple :

  • [sh](http://manpages.ubuntu.com/manpages/precise/en/man1/sh.1.html) -l
  • bash -l
  • [pdksh](http://manpages.ubuntu.com/manpages/precise/en/man1/pdksh.1.html) -l

C'est la meilleure façon de démarrer un Shell (sans se connecter) à moins que vous ne vouliez en démarrer un en tant que un autre utilisateur. Ensuite, utilisez :

  • [sudo](http://manpages.ubuntu.com/manpages/precise/en/man8/sudo.8.html) -i para root (utiliser sudo -s pour une racine non connectée et interactive Shell)
  • sudo -u _username_ -i pour tout utilisateur
  • [su](http://manpages.ubuntu.com/manpages/precise/en/man1/su.1.html) - _username_ pour les non root utilisateurs (utiliser su _username_ pour une racine non connectée et interactive Shell)

Qu'est-ce qu'un initial login Shell ?

Un site connexion initiale Shell est la même chose qu'un login Shell . Partout où cette réponse dit "login Shell", elle pourrait dire "login inital Shell" (sauf dans cette section, qui aurait déjà cessé d'avoir du sens).

Une raison pour laquelle le terme connexion initiale Shell c'est que login Shell est également utilisé dans un sens différent, pour identifier quel programme est utilisé comme le Shell qui est exécuté en se connectant. C'est le sens de login Shell avait l'habitude de dire :

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

Autres lectures

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X