Скрипты в /etc/profile.d игнорируются?

61

Я новичок в Ubuntu. У меня работает 13.10 Desktop.

Я хотел установить псевдонимы для всей системы и настраиваемое приглашение для bash. Я нашел эту статью:

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

Следуя советам в этой статье, я создал /etc/profiles.d/profile_local.sh. Он принадлежит пользователю root и имеет разрешения 644, как и другие скрипты:

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

Я также подтвердил, что / etc / profile вызывает /etc/profile.d. Содержит этот блок кода:

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_local.sh получен. Однако, если после входа в систему я 'source /etc.profile.d/profile_local.sh', я получаю ожидаемое поведение, мои пользовательские псевдонимы и пользовательское приглашение.

Что я делаю неправильно?

Содержимое скрипта 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
Нарисовался
источник
1
Нет, это не исполняемый файл, но и два других сценария. Однако я изменил это и попробовал снова. Все еще не повезло.
Дрю
3
Это не имеет ничего общего с добавлением .sh, это не имеет значения, и в любом случае файлы в profile.dисточнике, не выполняются, что немного отличается и не требует, чтобы файл был исполняемым. Проблема здесь в том, что profile& co не читаются сценариями без регистрации.
Тердон
1
Дрю, прочитай мой ответ. Файлы профиля игнорируются не входящими в систему оболочками, но вход в систему по умолчанию в графическом интерфейсе Ubuntu будет считывать некоторые из них. Просто используйте, .bashrcи все ваши проблемы уйдут. Существует также вопрос приоритета: если один из файлов, которые впоследствии будут прочитаны, также устанавливает PS1, то предыдущее значение будет отброшено. Во всяком случае, серьезно, не трогайте файлы /etc, играйте с теми, что у вас дома, и .bashrcне используйте профиль.
Terdon
1
Да, это должна быть оболочка входа в систему (именно такую ​​вещь вы должны включить в свой вопрос в следующий раз). Однако большинство систем имеют .profileфайлы по умолчанию в вашем доме, и настройки там перезаписывают все, что вы делаете /etc/profile. По сути, никогда не трогай, /etcесли не знаешь, что делаешь. Вот для чего нужны пользовательские файлы. Также, пожалуйста, отредактируйте свой вопрос и объясните, как именно вы подключаетесь, это все меняет.
Terdon
4
Пожалуйста, не делайте этого, используя /etc/profile.dдействительно плохую идею, которая затронет всех пользователей системы. Просто включите команды из profile_local.shв вашем ~/.profileили просто источник сценарий, добавив следующую строку в ~/.profile: . /path/to/profile_local.sh. ( .значит source, он прочитает предоставленный вами файл и выполнит найденные там команды).
Terdon

Ответы:

109

Чтобы понять, что здесь происходит, вам нужно понять небольшую справочную информацию о том, как работают оболочки (в данном случае bash).

  • Когда вы открываете эмулятор терминала ( gnome-terminalнапример), вы выполняете так называемую интерактивную оболочку , не входящую в систему .

  • Когда вы входите на свой компьютер из командной строки, через sshили запускаете такую ​​команду, как su - username, вы запускаете интерактивную оболочку входа .

  • Когда вы входите в систему графически, вы запускаете что-то совершенно другое, детали будут зависеть от вашей системы и графической среды, но в целом это графическая оболочка, которая обрабатывает ваш логин. Хотя многие графические оболочки (включая Ubuntu по умолчанию) будут читать, /etc/profileне все из них читают .

  • Наконец, когда вы запускаете сценарий оболочки, он запускается в неинтерактивной оболочке без входа в систему .

Теперь файлы, которые bash будет читать при запуске, зависят от типа оболочки, под которой он работает. Ниже приведен отрывок из раздела ПРИЗНАНИЕ man bash(выделено мной):

Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла / etc / profile , если этот файл существует. После прочтения этого файла он ищет ~ / .bash_profile, ~ / .bash_login и ~ / .profile в указанном порядке , а также читает и выполняет команды из первой, которая существует и доступна для чтения. Опция --noprofile может использоваться, когда оболочка запущена, чтобы запретить это поведение.

Когда запускается интерактивная оболочка, которая не является оболочкой входа в систему , bash читает и выполняет команды из /etc/bash.bashrc и ~ / .bashrc , если эти файлы существуют. Это может быть запрещено с помощью параметра --norc. Опция --rcfile file заставит bash читать и выполнять команды из файла вместо /etc/bash.bashrc и ~ / .bashrc.

Все это означает, что вы редактируете не тот файл. Вы можете проверить это, перейдя на виртуальную консоль с помощью Ctrl+ Alt+ F2(вернитесь к GUI с помощью Alt+ F7или, в F8зависимости от настроек) и войдя туда. Вы увидите, что ваша подсказка и псевдонимы доступны.

Таким образом, для того, чтобы параметр, который вы хотите применить, применялся к оболочкам, не входящим в систему, тип, который вы получаете каждый раз, когда открываете терминал, вы должны ~/.bashrcвместо этого внести свои изменения . Кроме того, вы также можете поместить свои псевдонимы в файл ~/.bash_aliases(однако, обратите внимание, что это функция Ubuntu, и вы не должны ожидать, что она будет работать в других дистрибутивах).

Подробнее о том, какой файл должен использоваться для чего, смотрите здесь .


ПРИМЕЧАНИЯ:

  • Debian (и, соответственно, Ubuntu) также имеет ~/.profileисходный код по умолчанию ~/.bashrc. Это означает , что любые изменения, внесенные ~/.bashrcтакже будут унаследованы оболочек входа в систему, но я) это не во всех машинах Linux / Unix и б) обратное не верно, поэтому вам следует вообще всегда работать с ~/.bashrc& сотрудничества , а не ~/.profileили /etc/profile,

  • Кроме того, общее примечание по использованию, изменения, внесенные в файлы конфигурации, /etcбудут влиять на всех пользователей. Обычно это не то, что вы хотите сделать, и его следует избегать. Вы всегда должны использовать эквивалентные файлы в вашем домашнем каталоге ( ~/).

  • Различные файлы конфигурации читаются последовательно. В частности, для оболочек входа в систему, порядок:

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

    Это означает, что любой параметр в ~/.profileбудет перезаписывать все, что установлено в предыдущих файлах.

Тердон
источник
1
Согласно этому сообщению howtolamp.com/articles/… , вы также можете запускать echo $0с терминала, и если вывод выводится с префиксом «-», то вы находитесь в оболочке входа в систему.
stackoverflower
@stackoverflower не в моей системе. Это работает для удаленной интерактивной оболочки входа в систему. Не похоже, когда работает bash -l. В любом случае, почему это актуально? Вопрос не в том, как проверить, какой тип оболочки вы используете.
Terdon
Великолепный пост, удивляюсь, почему он не появился в Google, когда у меня была такая же проблема
Донато
@stackoverflower Если "$0"расширяется до чего-то, что начинается с -, то вы знаете, что у вас есть оболочка входа. Но обратное неверно: отсутствие -не гарантирует, что вы не в оболочке входа. Наиболее распространенные способы запуска оболочек для входа в систему дают вам преимущество -, но не все. man bashговорит нам: « Оболочка для входа - это тот, чей первый символ аргумента ноль равен a -, или тот, который начинается с --loginопции». ( -lэто краткая форма --login; они эквивалентны .) В Bash вы можете запустить, shopt login_shellчтобы проверить.
Элия ​​Каган
2

Еще одна возможность, особенно для настройки , такие как настройки истории HISTSIZE, HISTFILESIZE, HISTCONTROLи PS1в том , что файлы загружаются, но настройки будут переписаны в другом файле , который является источником позже, с наиболее вероятным виновником является ~/.bashrc. (У меня есть набор настроек по умолчанию для наших серверов, например, приглашение root красного цвета для предупреждения пользователя и большие истории с отметками времени)

Ubuntu .bashrcиз по умолчанию /etc/skelустанавливает несколько настроек, которые, возможно, имело бы смысл установить откуда-то, где он не будет переопределять настройки, установленные владельцем системы из /etc/profile.d(Like /etc/bash.bashrc) (если пользователь редактирует их .bashrc, то можно перезаписать настройки, системные файлы по умолчанию) более раздражающие)

Герт ван ден Берг
источник
2

В Debian for Terminal session я решил эту проблему для всех пользователей так:

Добавлено в

sudo nano /etc/bash.bashrc

блок

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

из

/etc/profile
Николай Бараненко
источник
1

Следуйте по этому пути:

  • Открыть Редактировать -> Настройки
  • На первой вкладке «Общие» под меткой «Команда» включите «Запускать команду как оболочка входа»
макинтош
источник
-1

VERSION = "16.04.3 LTS (Xenial Xerus)"

Итак, все предположили, что этот человек не хочет /etc/profile.d/somefile.sh для всех пользователей, но в моем случае это именно то, что я хотел.

Так что на самом деле, как выясняется в Ubuntu, если вы используете это и хотите, чтобы оно вступило в силу в вашей графической оболочке, все, что вам нужно сделать, это установить файл, а затем выйти и снова войти. Все ваши консоли или все, что вы запускаете, будь то тип xterm или тип консоли (или переход в оболочку), теперь получат этот файл.

Не нужно использовать .bashrc и т. Д. Для всех пользователей. Извините, это просто не было ясно в ответе выше. Все, что они сказали, является правдой, но на самом деле это в основном не соответствует действительности, поскольку все, что запускает менеджер окон, унаследует эти настройки, поэтому просто войдите в систему и решите свою проблему и не беспокойтесь о .bashrc и т. Д., Если вы хотите применить его ко всем пользователям. ,

Исаак Кейн Эгглстоун
источник
2
Моя проблема именно в том, что это не происходит в терминале, работающем под графическим интерфейсом пользователя; ни в Ubuntu 16.04.3, ни в 18.04.
Томас Арилдсен,