Pourquoi / etc / profile n'est-il pas appelé pour les shells non connectés?

41

Connexion et shell sans connexion définis en tant que:

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, par exemple lorsque vous démarrez konsole (kde). / etc / profile est invoqué uniquement pour les shells de connexion.

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

    
posée James Mitch 26.01.2013 - 05:06
la source

1 réponse

86

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

Si vous voulez qu'une commande soit exécutée pour des shells interactifs non , et que vous utilisez bash , placez-la dans ~/.bashrc ou /etc/bash.bashrc .

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

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

  • Scripts en /etc/profile.d .

    Ceci est pour les shells de style Bourne, mais il n’est pas codé dans l’exécutable du shell lui-même. Au contraire, les commandes en /etc/profile les appellent. Par exemple, sur mon système Ubuntu 12.04, /etc/profile inclut 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 des shells compatibles Bourne au démarrage en tant que shell de connexion (sauf en cas de substitution, voir ci-dessous).

  • .bash_profile ou .bash_login dans le répertoire personnel de l'utilisateur. Celles-ci sont ignorées par les shells autres que bash . Mais si .bash_profile existe, bash l'exécute au lieu de .profile . Si .bash_profile n'existe pas mais que .bash_login existe, il s'exécute au lieu de .profile .

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

    L'avantage des fichiers profile spécifiques au shell est qu'ils peuvent contenir des commandes ou une syntaxe qui ne sont valides que pour ce shell. Par exemple, je peux utiliser l'opérateur d'évaluation [[ dans .bash_profile / .bash_login mais si je l'utilise dans .profile et que je me connecte avec dash comme shell, cela échouera.

Que faut-il rentrer 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 par un shell de connexion.) Si un shell est interactif, l'utilisateur qui l'exécute est probablement connecté, et il a probablement un ancêtre (qui l'a démarré ou a démarré ce qui l'a démarré, ou a commencé cela, etc.) qui était un shell de connexion.

Vous pourriez vouloir exécuter une commande une seule fois car:

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

À titre d'exemple de la deuxième situation, où un résultat indésirable se produirait, considérez 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 utilisé un autre shell ( zsh ), à un moment donné, vous avez décidé de retourner temporairement à bash mais de conserver votre environnement (donc, vous avez de nouveau lancé bash dans zsh ), puis vous avez exécuté un programme tel que mc qui exécute un shell dans le cadre de son interface. Si bin existe dans votre dossier de base et que 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

Cela est inefficace et (beaucoup plus important) rend difficile la compréhension du contenu de PATH .

Ce n’est en aucun cas un désastre. Autant que je sache, si chaque shell interactif contenait des fichiers "de profil", rien de grave n'arriverait, dans la configuration par défaut . Cependant, comme les fichiers "profile" ont pour but de contenir des commandes à exécuter une seule fois par login, un utilisateur ou un administrateur peut ajouter des commandes à un profil que doit uniquement exécuter lorsque démarrer un shell de connexion.

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

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

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

Ceci est le plus couramment utilisé pour les commandes

  1. n'affecte que l'environnement du shell dans lequel ils s'exécutent - pas même les shells enfants, ou
  2. doit fonctionner même si ce n’est pas le shell de connexion.

Par exemple, l’achèvement de l’onglet de ligne de commande doit généralement être activé, que bash soit ou non le shell de connexion. Donc, cela apparaît dans ~/.bashrc :

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

Là, 1 et 2 s'appliquent tous deux: cela ne se répercute pas sur les autres shells exécutés dans celui-ci, et la complétion par tabulation devrait fonctionner dans bash même si Je me suis connecté avec un autre shell.

Où placer des commandes pour les shells de connexion et les shells interactifs non connectés

Si vous utilisez bash et souhaitez qu'une commande s'exécute dans des shells de connexion et des shells interactifs et qui ne sont pas des shells de connexion, il suffit généralement de la placer dans /etc/bash.bashrc ou ~/.bashrc .En effet, /etc/profile et ~/.profile les exécutent explicitement par défaut. 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 pour bash .)

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

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

Vous ne souhaitez probablement pas spécifier de commandes à exécuter pour tous les shells non interactifs. ils s'exécuteraient 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 des bris importants. Si vous faites cela, 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 en fait exécutés , que le shell soit interactif ou non . Cependant, en haut, ils disent:

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

Donc, si vous avez besoin que les commandes s'exécutent automatiquement même dans les shells non interactifs comme ceux exécutés pour exécuter 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 souhaitez qu'un shell démarre après cela pour se comporter comme un shell de connexion, démarrez-le avec l'indicateur -l (signifie l ogin ). Par exemple:

C'est le meilleur moyen de démarrer un shell de connexion (sans se connecter), sauf si vous souhaitez en démarrer un en tant qu'utilisateur autre . Ensuite, utilisez:

  • sudo -i pour root (utilisez sudo -s pour un shell racine interactif sans connexion)
  • sudo -u username -i pour tout utilisateur
  • su - username pour les utilisateurs non root (utilisez su username pour un shell racine interactif sans connexion)

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 "shell de connexion", il pourrait dire "shell de connexion inital" (sauf dans cette section, qui aurait déjà cessé de faire sens).

Une des raisons de l’expression shell de connexion inital est que shell de connexion est également utilisé dans un autre sens - pour identifier quel programme est utilisé comme shell exécuté en se connectant. C'est le sens de shell de connexion utilisé pour dire:

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

Lectures complémentaires

réponse donnée Eliah Kagan 26.01.2013 - 08:27
la source

Lire d'autres questions sur les étiquettes