Skripte in /etc/profile.d werden ignoriert?

61

Ich bin neu in Ubuntu. Ich verwende 13.10 Desktop.

Ich wollte einige systemweite Aliase und eine benutzerdefinierte Eingabeaufforderung für Bash festlegen. Ich habe diesen Artikel gefunden:

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

Den Ratschlägen in diesem Artikel folgend, habe ich /etc/profiles.d/profile_local.sh erstellt. Es gehört root und hat die Berechtigungen 644, genau wie die anderen Skripte dort:

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

Ich habe weiterhin bestätigt, dass / etc / profile /etc/profile.d aufruft. Es enthält diesen Codeblock:

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

Bei der Anmeldung scheint es nicht so zu sein, dass das benutzerdefinierte Skript profile_local.sh, das ich erstellt habe, bezogen wird. Wenn ich mich jedoch nach dem Anmelden als "source /etc.profile.d/profile_local.sh" anmelde, erhalte ich das erwartete Verhalten, meine benutzerdefinierten Aliase und die benutzerdefinierte Eingabeaufforderung.

Was mache ich falsch?

Inhalt des Skripts '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
Drew
quelle
1
Nein, es ist nicht ausführbar, aber auch nicht die anderen beiden Skripte. Allerdings habe ich es geändert und erneut versucht. Immer noch kein Glück.
Drew
3
Dies hat nichts mit dem Hinzufügen zu tun .sh, es ist irrelevant, und die Dateien, aus profile.ddenen sie stammen, werden nicht ausgeführt, was sich geringfügig unterscheidet und keine ausführbare Datei erfordert. Das Problem hierbei ist, dass profile& co nicht von Nicht-Login-Skripten gelesen werden.
Terdon
1
Drew, lies meine Antwort. Die Profildateien werden von Nicht-Login-Shells ignoriert, aber Ubuntus Standard-GUI-Login liest einige von ihnen. Verwenden .bashrcSie einfach und alle Ihre Probleme werden verschwinden. Es ist auch eine Frage der Rangfolge, wenn eine der Dateien, die anschließend gelesen werden, auch PS1 setzt, wird der vorherige Wert verworfen. Wie auch immer, im Ernst, berühren Sie nicht die Ordner /etc, spielen Sie mit denen in Ihrem Heimverzeichnis und verwenden Sie .bashrckein Profil.
Terdon
1
Ja, das sollte eine Login-Shell sein (das ist die Art, wenn Sie es das nächste Mal in Ihre Frage aufnehmen sollten). Die meisten Systeme haben jedoch Standarddateien .profilein Ihrem Heim und die Einstellungen dort überschreiben alles, was Sie tun /etc/profile. Grundsätzlich niemals anfassen, es /etcsei denn, Sie wissen, was Sie tun. Dafür sind die benutzerspezifischen Dateien gedacht. Bitte bearbeite auch deine Frage und erkläre genau, wie du dich verbindest, das ändert alles.
Terdon
4
Bitte tun Sie dies nicht mit /etc/profile.deiner wirklich schlechten Idee, die alle Benutzer des Systems betrifft. Gerade ist die Befehle profile_local.shin Ihrem ~/.profileoder einfach das Skript beziehen , indem Sie diese Zeile in dem Hinzufügen ~/.profile: . /path/to/profile_local.sh. (Das .bedeutet source, es liest die Datei, die Sie ihm geben, und führt die Befehle aus, die es dort findet).
Terdon

Antworten:

109

Um zu verstehen, was hier vor sich geht, müssen Sie einige Hintergrundinformationen darüber verstehen, wie Shells (in diesem Fall bash) ausgeführt werden.

  • Wenn Sie beispielsweise einen Terminalemulator öffnen gnome-terminal, führen Sie eine sogenannte interaktive Shell ohne Anmeldung aus .

  • Wenn Sie sich über die Befehlszeile an Ihrem Computer anmelden sshoder einen Befehl ausführen, z. B. su - username, führen Sie eine interaktive Anmeldeshell aus .

  • Wenn Sie sich grafisch anmelden, wird etwas völlig anderes ausgeführt. Die Details hängen von Ihrem System und Ihrer grafischen Umgebung ab. Im Allgemeinen ist es jedoch die grafische Shell , die sich mit Ihrer Anmeldung befasst. Während viele Grafik-Shells (einschließlich der Ubuntu-Standard-Shells) /etc/profilenicht alle von ihnen lesen .

  • Wenn Sie ein Shell-Skript ausführen, wird es in einer nicht interaktiven Shell ohne Anmeldung ausgeführt .

Nun hängen die Dateien, die beim Start von bash gelesen werden, von der Art der Shell ab, unter der sie ausgeführt wird. Das Folgende ist ein Auszug aus dem Abschnitt INVOCATION von man bash(Schwerpunkt Mine):

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der Option --login aufgerufen wird, werden zuerst Befehle aus der Datei / etc / profile gelesen und ausgeführt , sofern diese Datei vorhanden ist. Nach dem Lesen dieser Datei sucht sie in dieser Reihenfolge nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile und liest und führt Befehle von der ersten Datei aus, die vorhanden und lesbar ist. Die Option --noprofile kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu unterbinden.

Wenn eine interaktive Shell , das ist kein Login - Shell gestartet wird, bash liest und führt Befehle aus /etc/bash.bashrc und ~ / .bashrc , wenn diese Dateien vorhanden sind . Dies kann mit der Option --norc verhindert werden. Die Option --rcfile file erzwingt, dass Bash anstelle von /etc/bash.bashrc und ~ / .bashrc Befehle aus der Datei liest und ausführt.

Dies bedeutet, dass Sie die falsche Datei bearbeiten. Sie können dies testen, indem Sie auf eine virtuelle Konsole mit Ctrl+ Alt+ F2(kehren Sie mit Alt+ F7oder F8abhängig von Ihrem Setup zur GUI zurück ) fallen und sich dort anmelden. Sie werden sehen, dass Ihre Eingabeaufforderung und Aliase verfügbar sind.

Damit die gewünschte Einstellung auf nicht angemeldete Shells angewendet wird, sollten Sie ~/.bashrcstattdessen die Änderungen vornehmen, die Sie bei jedem Öffnen eines Terminals erhalten . Alternativ können Sie auch Ihre Aliase in die Datei einfügen ~/.bash_aliases(beachten Sie jedoch, dass dies eine Ubuntu-Funktion ist und Sie nicht erwarten sollten, dass sie auf anderen Distributionen funktioniert).

Weitere Informationen dazu, welche Datei für welche Zwecke verwendet werden soll, finden Sie hier .


ANMERKUNGEN:

  • Debian (und durch Erweiterung Ubuntu) hat auch die ~/.profileStandardquelle ~/.bashrc. Dies bedeutet, dass alle Änderungen, die Sie vornehmen, ~/.bashrcauch von Login-Shells übernommen werden. I) Dies ist jedoch nicht bei allen Linux / Unix-Maschinen der Fall, und ii) das Gegenteil ist nicht der Fall, weshalb Sie im Allgemeinen immer mit ~/.bashrc& co anstatt mit ~/.profileoder arbeiten sollten /etc/profile.

  • Ein allgemeiner Hinweis zur Verwendung sowie Änderungen an den Konfigurationsdateien in /etcwirken sich auf alle Benutzer aus. Dies ist normalerweise nicht das, was Sie tun möchten und sollte vermieden werden. Sie sollten immer die entsprechenden Dateien in Ihrem Home-Verzeichnis verwenden ( ~/).

  • Die verschiedenen Konfigurationsdateien werden nacheinander gelesen. Insbesondere für Login-Shells lautet die Reihenfolge:

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

    Dies bedeutet, dass alle Einstellungen ~/.profilein den vorherigen Dateien alle Einstellungen überschreiben.

terdon
quelle
1
Nach diesem Beitrag können Sie howtolamp.com/articles/… auch echo $0von einem Terminal aus ausführen. Wenn der Ausgabe ein "-" vorangestellt ist, befinden Sie sich in einer Anmeldeshell.
Stackoverflower
@stackoverflower nicht auf meinem System. Dies funktioniert für eine interaktive Remote-Anmeldeshell. Scheint nicht zu laufen bash -l. Warum ist das auf jeden Fall relevant? Die Frage ist nicht, wie Sie überprüfen können, welche Art von Shell Sie ausführen.
Terdon
Wunderschöner Beitrag, frage mich, warum er bei Google nicht aufgetaucht ist, als ich das gleiche Problem hatte
Donato
@stackoverflower Wenn es "$0"zu etwas erweitert wird, das mit beginnt -, wissen Sie, dass Sie eine Anmeldeshell haben. Das Gegenteil ist jedoch nicht der Fall: Das Fehlen von -stellt nicht sicher, dass Sie sich nicht in einer Anmeldeshell befinden. Die gebräuchlichsten Methoden zum Starten von Login-Shells führen Sie an -, aber nicht alle. man bashteilt uns mit "Eine Login-Shell ist eine Shell, deren erstes Zeichen des Arguments Null ein ist -, oder eine Shell , die mit der --loginOption gestartet wurde ." ( -list die Kurzform von --login; sie sind gleichwertig .) In Bash können Sie ausführen shopt login_shell, um zu überprüfen.
Eliah Kagan
2

Eine weitere Möglichkeit, vor allem für Einstellungen wie die Geschichte Einstellungen HISTSIZE, HISTFILESIZE, HISTCONTROL, und PS1ist , dass die Dateien geladen werden, aber Einstellungen werden in einer anderen Datei überschreibt , die Quelle später ist, mit dem wahrscheinlichste Täter zu sein ~/.bashrc. (Ich habe einen Standardsatz von Einstellungen für unsere Server, wie eine rote Eingabeaufforderung für root, um den Benutzer zu warnen, und große Historien mit Zeitstempeln.)

Das Standard-Ubuntu .bashrcvon /etc/skellegt mehrere Einstellungen fest, die möglicherweise sinnvoll waren, um Einstellungen zu ändern, die vom Systembesitzer von /etc/profile.d(Gefällt mir /etc/bash.bashrc) festgelegt wurden (Wenn ein Benutzer sie bearbeitet .bashrc, können die Standarddateien des Systems problemlos überschrieben werden nerviger sind)

Gert van den Berg
quelle
2

In der Debian for Terminal-Sitzung habe ich dieses Problem für alle Benutzer so gelöst:

hinzugefügt zu

sudo nano /etc/bash.bashrc

Block

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

von

/etc/profile
Nikolay Baranenko
quelle
1

Folge diesem Pfad:

  • Öffnen Sie Bearbeiten -> Einstellungen
  • Aktivieren Sie auf der ersten Registerkarte "Allgemein" unter "Befehl" die Option "Befehl als Anmeldeshell ausführen".
Mac
quelle
-1

VERSION = "16.04.3 LTS (Xenial Xerus)"

Okay, alle sind davon ausgegangen, dass die Person hier nicht für alle Benutzer /etc/profile.d/somefile.sh möchte, aber in meinem Fall ist das genau das, was ich wollte.

Wie sich bei Ubuntu herausstellt, müssen Sie nur die Datei festlegen und sich dann abmelden und wieder anmelden, wenn Sie dies verwenden und möchten, dass es in Ihrer grafischen Shell wirksam wird. Alle Ihre Konsolen oder alles, was Sie starten, ob es sich um einen xterm-Typ oder einen Konsolentyp handelt (oder auf die Shell abgelegt wird), haben jetzt diese Datei bezogen.

Es ist nicht erforderlich, .bashrc usw. für alle Benutzer zu verwenden. Entschuldigung, das war in der obigen Antwort einfach nicht klar. Alles, was sie sagten, ist wahr, aber in Wirklichkeit ist es meistens nicht wahr, da alles, was der Windows-Manager startet, diese Einstellungen erbt. Melden Sie sich einfach erneut an und lösen Sie Ihr Problem .

Isaac Kane Egglestone
quelle
2
Mein Problem ist genau, dass dies nicht im Terminal unter der grafischen Benutzeroberfläche passiert; weder in Ubuntu 16.04.3 noch 18.04.
Thomas Arildsen