Skrypty w /etc/profile.d Czy jesteś ignorowany?

61

Jestem nowy w Ubuntu. Korzystam z pulpitu 13.10.

Chciałem ustawić aliasy dla całego systemu i niestandardowy monit o bash. Znalazłem ten artykuł:

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

Postępując zgodnie z radami zawartymi w tym artykule, utworzyłem /etc/profiles.d/profile_local.sh. Jest własnością root i ma uprawnienia 644, podobnie jak inne skrypty:

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

Potwierdziłem ponadto, że / etc / profile wywołuje /etc/profile.d. Zawiera ten blok kodu:

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

Po zalogowaniu nie wygląda na to, że utworzony przeze mnie skrypt niestandardowy profile_local.sh został pobrany. Jednak jeśli po zalogowaniu I 'source /etc.profile.d/profile_local.sh', otrzymuję oczekiwane zachowanie, moje niestandardowe aliasy i niestandardowy monit.

Co ja robię źle?

Zawartość skryptu „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
Rysował
źródło
1
Nie, nie jest wykonywalny, ale dwa pozostałe skrypty też. Jednak zmieniłem to i spróbowałem ponownie. Wciąż nie ma szczęścia.
Drew
3
Nie ma to nic wspólnego z dodawaniem .sh, jest nieistotne i tak czy inaczej pliki profile.dsą pobierane, nie są wykonywane, co jest nieco inne i nie wymaga pliku do wykonania. Problem polega na tym, że profile& co nie są odczytywane przez skrypty niezalogowane.
terdon
1
Drew, przeczytaj moją odpowiedź. Pliki profilu są ignorowane przez powłoki niezalogowane, ale domyślny login GUI Ubuntu odczyta niektóre z nich. Po prostu użyj, .bashrca wszystkie twoje problemy znikną. Istnieje również kwestia pierwszeństwa, jeśli jeden z odczytanych plików później również ustawi PS1, wówczas poprzednia wartość zostanie odrzucona. W każdym razie, na poważnie, nie dotykaj filtrów /etc, baw się z tymi w swoim domowym katalogu i .bashrcnie używaj profilu.
terdon
1
Tak, powinna to być powłoka logowania (to jest coś, co należy dołączyć do pytania następnym razem). Jednak większość systemów ma .profilew domu pliki domyślne, a ustawienia tam zastąpią wszystko, co robisz /etc/profile. Zasadniczo nigdy nie dotykaj, /etcchyba że wiesz, co robisz. Do tego służą pliki specyficzne dla użytkownika. Także, proszę edytować swoje pytanie i dokładnie wyjaśnić, w jaki sposób łączysz się, że wszystko się zmienia.
terdon
4
Nie rób tego, /etc/profile.dponieważ jest to naprawdę zły pomysł i wpłynie na wszystkich użytkowników systemu. Wystarczy zawierać poleceń profile_local.shw twojej ~/.profilelub po prostu źródło skrypt dodając ten wiersz do ~/.profile: . /path/to/profile_local.sh. ( .oznacza to source, że przeczyta podany plik i uruchomi znalezione tam polecenia).
terdon

Odpowiedzi:

108

Aby zrozumieć, co się tutaj dzieje, musisz zrozumieć kilka podstawowych informacji o tym, jak działają powłoki (w tym przypadku bash).

  • Po otwarciu emulatora terminala ( gnome-terminalna przykład) uruchamia się tak zwaną interaktywną powłokę bez możliwości logowania .

  • Po zalogowaniu się do komputera z poziomu wiersza poleceń, za pomocą sshlub uruchomieniu polecenia, takiego jak su - usernameuruchomiona jest interaktywna powłoka logowania .

  • Kiedy logujesz się graficznie, uruchamiasz coś zupełnie innego, szczegóły będą zależeć od twojego systemu i środowiska graficznego, ale ogólnie to graficzna powłoka zajmuje się twoim logowaniem. Podczas gdy wiele powłok graficznych (w tym domyślna wersja Ubuntu) będzie czytać, /etc/profilenie wszystkie.

  • Wreszcie, po uruchomieniu skryptu powłoki, jest on uruchamiany w nieinteraktywnej powłoce niezalogowanej .

Teraz pliki, które bash odczyta po uruchomieniu, zależą od typu powłoki, w jakiej działa. Poniżej znajduje się fragment sekcji ZAPROSZENIE man bash(moje wyróżnienie ):

Gdy bash jest wywoływany jako interaktywna powłoka logowania lub jako nieinteraktywna powłoka z opcją --login, najpierw czyta i wykonuje polecenia z pliku / etc / profile , jeśli plik ten istnieje. Po odczytaniu tego pliku szuka ~ / .bash_profile, ~ / .bash_login i ~ / .profile, w tej kolejności , i odczytuje i wykonuje polecenia z pierwszego, który istnieje i jest czytelny. Opcji --noprofile można użyć, gdy powłoka zostanie uruchomiona w celu zahamowania tego zachowania.

Po uruchomieniu interaktywnej powłoki, która nie jest powłoką logowania , bash czyta i wykonuje polecenia z /etc/bash.bashrc i ~ / .bashrc , jeśli te pliki istnieją. Można temu zapobiec, używając opcji --norc. Opcja --rcfile pliku zmusi bash do odczytu i wykonywania poleceń z pliku zamiast /etc/bash.bashrc i ~ / .bashrc.

Oznacza to, że edytujesz niewłaściwy plik. Możesz to przetestować, upuszczając na wirtualną konsolę za pomocą Ctrl+ Alt+ F2(powrót do GUI za pomocą Alt+ F7lub w F8zależności od konfiguracji) i zalogowanie się tam. Zobaczysz, że twój monit i aliasy są dostępne.

Tak więc, aby zastosować ustawienie, które chcesz zastosować do powłok niezalogowanych, typu, który otrzymujesz za każdym razem, gdy otwierasz terminal, powinieneś wprowadzić zmiany ~/.bashrc. Alternatywnie możesz także umieścić swoje aliasy w pliku ~/.bash_aliases(jednak pamiętaj, że jest to funkcja Ubuntu i nie powinieneś oczekiwać, że będzie działać w innych dystrybucjach).

Aby uzyskać więcej informacji na temat tego, którego pliku należy użyć do tego, zobacz tutaj .


UWAGI:

  • Debian (i przez rozszerzenie Ubuntu) ma również domyślne ~/.profileźródło ~/.bashrc. Oznacza to, że wszelkie zmiany, które wprowadzisz, ~/.bashrczostaną odziedziczone przez powłoki logowania, ale i) nie jest tak w przypadku wszystkich maszyn z systemem Linux / Unix i ii) odwrotność nie jest prawdą, dlatego na ogół powinieneś zawsze pracować z ~/.bashrc& co, a nie ~/.profilelub /etc/profile.

  • Również ogólna uwaga na temat użytkowania, zmiany wprowadzone w plikach konfiguracyjnych w /etcwpłyną na wszystkich użytkowników. To zwykle nie jest to, co chcesz robić i należy tego unikać. Zawsze powinieneś używać równoważnych plików w swoim katalogu domowym ( ~/).

  • Różne pliki konfiguracyjne są odczytywane sekwencyjnie. W szczególności dla powłok logowania kolejność jest następująca:

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

    Oznacza to, że każde ustawienie ~/.profilezastąpi wszystko ustawione w poprzednich plikach.

terdon
źródło
1
Zgodnie z tym postem howtolamp.com/articles/… , możesz również uruchomić echo $0z terminala, a jeśli dane wyjściowe są poprzedzone znakiem „-”, jesteś w powłoce logowania.
stackoverflower
@stackoverflower nie ma w moim systemie. Działa to dla zdalnej, interaktywnej powłoki logowania. Nie wydaje się, gdy działa bash -l. W każdym razie, dlaczego to jest tak istotne? Pytanie nie dotyczy tego, jak sprawdzić, jaki rodzaj powłoki używasz.
terdon
wspaniały post, zastanawiam się, dlaczego nie pojawił się w google, gdy miałem ten sam problem
Donato
@stackoverflower Jeśli "$0"rozwija się do czegoś, co zaczyna się od -, to wiesz, że masz powłokę logowania. Ale odwrotność nie jest prawdą: brak -nie gwarantuje, że nie jesteś w powłoce logowania. Najpopularniejsze sposoby uruchamiania powłok logowania dają wiodące -, ale nie wszystkie. man bashmówi nam: Powłoka logowania to taka, której pierwszym znakiem argumentu zero jest -lub zaczyna się od --loginopcji”. ( -lto krótka forma --login; są równoważne ). W Bash możesz biegać, shopt login_shellaby sprawdzić.
Eliah Kagan
2

Inną możliwością, zwłaszcza dla ustawień, takich jak ustawienia historii HISTSIZE, HISTFILESIZE, HISTCONTROL, i PS1to, że pliki są ładowane, ale ustawienia są nadpisywane w innym pliku, który jest źródłem później, z najbardziej prawdopodobnym winowajcą jest ~/.bashrc. (Mam domyślny zestaw ustawień dla naszych serwerów, takich jak czerwony monit dla użytkownika root, aby ostrzec użytkownika i duże historie za pomocą znaczników czasu)

Domyślny system Ubuntu .bashrcz /etc/skelustawia kilka ustawień, które mogłyby mieć sens, aby ustawić je z miejsca, w którym nie zastąpiłoby ustawień ustawionych przez właściciela systemu z /etc/profile.d(Lubię to /etc/bash.bashrc) (Jeśli użytkownik je edytuje .bashrc, można zastąpić ustawienia, domyślne pliki systemowe są bardziej denerwujące)

Gert van den Berg
źródło
2

w sesji Debian for Terminal rozwiązałem ten problem dla wszystkich użytkowników, więc:

dodano do

sudo nano /etc/bash.bashrc

blok

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

od

/etc/profile
Nikołaj Baranenko
źródło
1

Podążaj tą ścieżką:

  • Otwórz Edycja -> Preferencje
  • Na pierwszej karcie „Ogólne”, pod etykietą „Polecenie”, włącz „Uruchom polecenie jako powłokę logowania”
Prochowiec
źródło
-1

WERSJA = „16.04.3 LTS (Xenial Xerus)”

Okej, więc wszyscy założyli, że osoba tutaj nie chce /etc/profile.d/somefile.sh dla wszystkich użytkowników, ale w moim przypadku właśnie tego chciałem.

Tak więc, jak się okazuje z Ubuntu, jeśli go używasz i chcesz, aby zadziałał w graficznej powłoce, wszystko, co musisz zrobić, to ustawić plik, a następnie wylogować się i ponownie zalogować. Wszystkie twoje konsole lub cokolwiek, co uruchomisz, bez względu na to, czy będzie to typ xterm czy typ konsoli (lub upuszczenie do powłoki), będzie teraz mieć ten plik.

Nie trzeba używać .bashrc itp. Dla wszystkich użytkowników. Przepraszamy, to po prostu nie było jasne w powyższej odpowiedzi. Wszystko, co powiedzieli, jest prawdą, ale w rzeczywistości jest to w większości nieprawda, ponieważ wszystko, co uruchamia menedżer systemu Windows, odziedziczy te ustawienia, więc po prostu zaloguj się ponownie i rozwiąż problem i nie zawracaj sobie głowy .bashrc itp., Jeśli masz zamiar zastosować go do wszystkich użytkowników .

Izaak Kane Egglestone
źródło
2
Mój problem polega dokładnie na tym, że tak się nie dzieje w terminalu uruchomionym pod graficznym interfejsem użytkownika; ani w Ubuntu 16.04.3, ani 18.04.
Thomas Arildsen