Les scripts dans /etc/profile.d sont ignorés?

61

Je suis nouveau sur Ubuntu. J'exécute 13.10 Desktop.

Je voulais définir des alias système et une invite personnalisée pour bash. J'ai trouvé cet article:

https://help.ubuntu.com/community/EnvironmentVariables

En suivant les conseils de cet article, j'ai créé /etc/profiles.d/profile_local.sh. Il est la propriété de root et possède les autorisations de 644, tout comme les autres scripts de cet emplacement:

root@ubuntu:/etc/profile.d# ll
total 28
drwxr-xr-x   2 root root  4096 Mar 23 08:56 .
drwxr-xr-x 135 root root 12288 Mar 23 09:15 ..
-rw-r--r--   1 root root   660 Oct 23  2012 bash_completion.sh
-rw-r--r--   1 root root  3317 Mar 23 07:36 profile_local.sh
-rw-r--r--   1 root root  1947 Nov 23 00:57 vte.sh

J'ai également confirmé que / etc / profile appelle /etc/profile.d. Il contient ce bloc de code:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Lors de la connexion, il ne semble pas que le script personnalisé profile_local.sh que j'ai créé soit identifié. Toutefois, si, après la connexion, je source /etc.profile.d/profile_local.sh, le comportement attendu, mes alias personnalisés et mes invites personnalisées me sont fournis.

Qu'est-ce que je fais mal?

Contenu du script 'profile_local.sh':

# 3/23/14 - Copied from Gentoo /etc/bash/bashrc
# Placed in /etc/profile.d as described at:
# https://help.ubuntu.com/community/EnvironmentVariables

# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !


# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
        # Shell is non-interactive.  Be done now!
        return
fi

# Bash won't get SIGWINCH if another process is in the foreground.
# Enable checkwinsize so that bash will check the terminal size when
# it regains control.  #65623
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
shopt -s checkwinsize

# Enable history appending instead of overwriting.  #139609
shopt -s histappend

# Change the window title of X terminals 
case ${TERM} in
        xterm*|rxvt*|Eterm|aterm|kterm|gnome*|interix)
                PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                ;;
        screen)
                PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
                ;;
esac

use_color=false

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
        && type -P dircolors >/dev/null \
        && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
        # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
        if type -P dircolors >/dev/null ; then
                if [[ -f ~/.dir_colors ]] ; then
                        eval $(dircolors -b ~/.dir_colors)
                elif [[ -f /etc/DIR_COLORS ]] ; then
                        eval $(dircolors -b /etc/DIR_COLORS)
                fi
        fi

        if [[ ${EUID} == 0 ]] ; then
                PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
        else
                PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
        fi

        alias ls='ls --color=auto'
        alias grep='grep --colour=auto'
else
        if [[ ${EUID} == 0 ]] ; then
                # show root@ when we don't have colors
                PS1='\u@\h \W \$ '
        else
                PS1='\u@\h \w \$ '
        fi
fi

# Try to keep environment pollution down, EPA loves us.
unset use_color safe_term match_lhs

TZ="PST8PDT"

alias ll='ls -la'
alias dig='dig +search'
alias dir='ls -ba'

alias edit="ee"
alias ss="ps -aux"
alias dot='ls .[a-zA-Z0-9_]*'
alias news="xterm -g 80x45 -e trn -e -S1 -N &"

alias more="less"
alias c="clear"
alias m="more"
alias j="jobs"

# common misspellings
alias mroe=more
alias pdw=pwd
A dessiné
la source
1
Non, ce n'est pas exécutable, mais les deux autres scripts non plus. Cependant, j'ai changé et réessayé. Toujours pas de chance.
Drew
3
Cela n'a rien à voir avec l'ajout .sh, ce n'est pas pertinent et, de toute façon, les fichiers profile.dsont générés, pas exécutés, ce qui est légèrement différent et n'exige pas que le fichier soit exécutable. Le problème ici est que profile& co ne sont pas lus par des scripts non-login.
terdon
1
Drew, lisez ma réponse. Les fichiers de profil sont ignorés par les shells non connectés, mais la connexion par défaut à l'interface graphique d'Ubuntu en lira certains. Utilisez simplement .bashrcet tous vos problèmes disparaîtront. Il y a aussi une question de priorité: si l'un des fichiers lus par la suite définit également PS1, la valeur précédente sera alors ignorée. Quoi qu'il en soit, sérieusement, ne touchez pas les utilisateurs /etc, jouez avec ceux de votre répertoire personnel et n'utilisez .bashrcpas de profil.
terdon
1
Oui, cela devrait être un shell de connexion (c'est le genre de chose que vous devriez inclure dans votre question la prochaine fois). Cependant, la plupart des systèmes ont des .profilefichiers par défaut dans votre maison et les paramètres qu’ils remplacent écrasent tout ce que vous faites /etc/profile. En gros, ne touchez jamais à/etc moins de savoir ce que vous faites. C'est à cela que servent les fichiers spécifiques à l'utilisateur. Aussi, veuillez modifier votre question et expliquer comment vous vous connectez, cela change tout.
terdon
4
S'il vous plaît ne faites pas cela en utilisant /etc/profile.dc'est une très mauvaise idée et affectera tous les utilisateurs du système. Il suffit d' inclure les commandes de profile_local.shvotre ~/.profileou simplement la source du script en ajoutant cette ligne à votre ~/.profile: . /path/to/profile_local.sh. (le .moyen source, il va lire le fichier que vous lui donnez et exécuter les commandes qu'il y trouve).
terdon

Réponses:

109

Pour comprendre ce qui se passe ici, vous devez comprendre un peu d’informations générales sur la façon dont les shells (bash dans ce cas) sont exécutés.

  • Lorsque vous ouvrez un émulateur de terminal ( gnome-terminalpar exemple), vous exécutez ce qu'on appelle un shell interactif sans connexion .

  • Lorsque vous vous connectez à votre ordinateur à partir de la ligne de commande, via sshou exécutez une commande telle que su - username, vous exécutez un shell de connexion interactif .

  • Lorsque vous vous connectez graphiquement, vous utilisez quelque chose de complètement différent, les détails dépendront de votre système et de votre environnement graphique, mais en général, c'est le shell graphique qui gère vos identifiants. Bien que de nombreux shells graphiques (y compris celui par défaut d’Ubuntu) ne les liront /etc/profilepas tous.

  • Enfin, lorsque vous exécutez un script shell, il est exécuté dans un shell non interactif et non connecté .

Désormais, les fichiers que bash lira au lancement dépendent du type de shell sous lequel il s'exécute. Ce qui suit est un extrait de la section INVOCATION de man bash(souligné par moi):

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l'option --login, il commence par lire et exécuter les commandes du fichier / etc / profile , si ce fichier existe. Après avoir lu ce fichier, il recherche ~ / .bash_profile, ~ / .bash_login et ~ / .profile, dans cet ordre , puis lit et exécute les commandes à partir de la première qui existe et est lisible. L'option --noprofile peut être utilisée au démarrage du shell pour empêcher ce comportement.

Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes de /etc/bash.bashrc et ~ / .bashrc , si ces fichiers existent. Cela peut être inhibé en utilisant l'option --norc. L'option de fichier --rcfile obligera bash à lire et à exécuter des commandes à partir du fichier au lieu de /etc/bash.bashrc et ~ / .bashrc.

Tout ce que cela signifie, c'est que vous éditez le mauvais fichier. Vous pouvez tester cela en accédant à une console virtuelle à l'aide de Ctrl+ Alt+ F2(revenir à l'interface graphique avec Alt+ F7, ou en F8fonction de votre configuration) et en vous y connectant. Vous verrez que votre invite et vos alias sont disponibles.

Par conséquent, pour que le paramètre souhaité soit appliqué aux shells ne se connectant pas, le type que vous obtenez à chaque fois que vous ouvrez un terminal, vous devez apporter vos modifications à la ~/.bashrcplace. Vous pouvez également placer vos alias dans le fichier ~/.bash_aliases(toutefois, notez qu'il s'agit d'une fonctionnalité Ubuntu et que vous ne devriez pas vous attendre à ce qu'elle fonctionne sur d'autres distributions).

Pour plus de détails sur quel fichier doit être utilisé pour quoi, voir ici .


REMARQUES:

  • Debian (et par extension Ubuntu) a également la ~/.profilesource par défaut ~/.bashrc. Cela signifie que toutes les modifications que vous apportez ~/.bashrcseront également héritées par les shells de login, mais i) ce n'est pas le cas sur toutes les machines Linux / Unix et ii) l'inverse n'est pas vrai, raison pour laquelle vous devriez généralement toujours travailler avec ~/.bashrc& co plutôt que ~/.profileou /etc/profile.

  • De plus, une remarque générale sur l'utilisation, les modifications apportées aux fichiers de configuration /etcaffectera tous les utilisateurs. Ce n'est généralement pas ce que vous voulez faire et devrait être évité. Vous devez toujours utiliser les fichiers équivalents dans votre répertoire personnel ( ~/).

  • Les différents fichiers de configuration sont lus de manière séquentielle. Plus précisément, pour les shells de connexion, la commande est la suivante:

    /etc/profile -> /etc/profile.d/* (in alphabetical order) -> ~/.profile

    Cela signifie que tout paramètre ~/.profileinséré écrasera tout élément défini dans les fichiers précédents.

terdon
la source
1
Selon ce post howtolamp.com/articles/… , vous pouvez également exécuter à echo $0partir d'un terminal et si la sortie est préfixée d'un "-", vous êtes dans un shell de connexion.
stackoverflower
@stackoverflower pas sur mon système. Cela fonctionne pour un shell de connexion interactif à distance. Ne semble pas en courant bash -l. En tout cas, pourquoi est-ce pertinent? La question n'est pas de savoir comment vérifier quel type de shell vous utilisez.
terdon
post magnifique, je me demande pourquoi il n'est pas apparu sur Google quand j'ai eu le même problème
Donato
@stackoverflower Si "$0"s'étend à quelque chose qui commence par -, alors vous savez que vous avez un shell de connexion. Mais l'inverse n'est pas vrai: l'absence de -ne garantit pas que vous n'êtes pas dans un shell de connexion. La plupart des méthodes courantes de démarrage des coquilles de connexion vous donnent un avantage -, mais pas toutes. man bashnous dit "Un shell de connexion est un shell dont le premier caractère de l'argument zéro est un -, ou un code commençant par l' --loginoption." ( -lest la forme abrégée de --login; ils sont équivalents .) Dans Bash, vous pouvez exécuter shopt login_shellpour vérifier.
Eliah Kagan
2

Une autre possibilité, en particulier pour les paramètres tels que les paramètres de l' historique HISTSIZE, HISTFILESIZE, HISTCONTROLet PS1que les fichiers sont chargés, mais les paramètres sont écrasés dans un autre fichier qui est la source plus tard, le coupable le plus probable étant ~/.bashrc. (J'ai un ensemble de paramètres par défaut pour nos serveurs, par exemple une invite rouge pour root avertissant l'utilisateur et des historiques volumineux avec horodatage)

La valeur par défaut Ubuntu à .bashrcpartir /etc/skeldéfinit plusieurs paramètres, ce qui pourrait avoir fait sens pour mettre quelque part où il ne serait pas remplacer les paramètres définis par le propriétaire du système de /etc/profile.d(comme /etc/bash.bashrc) (Si un utilisateur modifie leur .bashrc, il est très bien pour remplacer les paramètres, les fichiers par défaut du système sont plus ennuyeux)

Gert van den Berg
la source
2

dans Debian pour Terminal Session, j’ai résolu ce problème pour tous les utilisateurs:

ajouté à

sudo nano /etc/bash.bashrc

bloquer

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

de

/etc/profile
Nikolay Baranenko
la source
1

Suivez ce chemin:

  • Ouvrez Édition -> Préférences
  • Dans le premier onglet "Général", sous le libellé "Commande", activez "Exécuter la commande en tant que shell de connexion".
Mac
la source
-1

VERSION = "16.04.3 LTS (Xenial Xerus)"

Donc tout le monde a supposé que la personne ici ne voulait pas /etc/profile.d/somefile.sh pour tous les utilisateurs, mais dans mon cas, c’est exactement ce que je voulais.

Donc, en réalité, comme cela s’est passé avec Ubuntu, si vous utilisez ceci et que vous voulez que cela prenne effet dans votre shell graphique, il vous suffit de définir le fichier, puis de vous déconnecter, puis de revenir. Ce fichier est maintenant généré par toutes vos consoles ou tout ce que vous lancez, qu’il s’agisse d’un type xterm ou d’une console (ou en passant au shell).

Pas besoin d'utiliser .bashrc etc. pour tous les utilisateurs. Désolé, ce n'était pas clair dans la réponse ci-dessus. Tout ce qu’ils ont dit est vrai, mais en réalité, c’est faux, car tout ce que le gestionnaire de fenêtres lance héritera de ces paramètres. Vous devez donc vous reconnecter et résoudre votre problème. Ne vous embêtez pas avec .bashrc, etc. si vous souhaitez l’appliquer à tous les utilisateurs. .

Isaac Kane Egglestone
la source
2
Mon problème est précisément que cela ne se produit pas dans le terminal exécuté sous l'interface utilisateur graphique; ni dans Ubuntu 16.04.3 ni 18.04.
Thomas Arildsen