Почему / etc / profile не вызывается для не входящих в систему оболочек?

51

Оболочка для входа и не входа в систему определяется как:

su - $USER # will give you a login shell
bash # will give you a non-login shell

/ etc / profile не вызывается для оболочек без входа в систему, например, когда вы запускаете konsole (kde). / etc / profile вызывается только для оболочек входа в систему.

Почему это? Пожалуйста, объясните, потому что мне нравится понимать обоснование этого.

Джеймс Митч
источник

Ответы:

100

/etc/profile вызывается только для оболочек входа в систему, потому что это его конкретное назначение.

Если вы хотите, чтобы команда выполнялась для интерактивных оболочек, которые не являются оболочками входа в систему, и вы используете ее bash, введите ее ~/.bashrcили /etc/bash.bashrc.

Назначение файлов профиля состоит в том, чтобы содержать команды, которые должны выполняться только для оболочек входа в систему. Эти файлы:

  • /etc/profile, запускается всеми Bourne-совместимыми оболочками (включая bashи dash) при запуске в качестве оболочки входа в систему.

  • Скрипты в /etc/profile.d.

    Это для оболочек в стиле Борна, но оно не закодировано в самом исполняемом файле оболочки. Скорее, команды в /etc/profileних вызывают. Например, в моей системе Ubuntu 12.04 /etc/profileесть следующие строки:

    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 в домашнем каталоге пользователя, запускается совместимыми с Bourne оболочками при запуске в качестве оболочки входа в систему (если не переопределена, см. ниже).

  • .bash_profileили .bash_loginв домашнем каталоге пользователя. Они игнорируются другими оболочками bash. Но если .bash_profileсуществует, bashзапускает его вместо .profile . Если .bash_profileне существует, но .bash_loginсуществует, то запускается вместо .profile.

    (Но это обычно для .bash_profileили .bash_login, когда это существует, быть написанным так, чтобы * явно вызывать .profile.)

    Преимущество специфичных для оболочки файлов профиля состоит в том, что они могут содержать команды или синтаксис, которые действительны только для этой оболочки. Например, я могу использовать [[оператор оценки в .bash_profile/, .bash_loginно если я использую его, .profileа затем войду в систему dashкак моя оболочка, произойдет сбой.

Что должно идти в "профильных" файлах

«профильные» файлы должны содержать команды, которые должны запускаться только один раз, в начале входа в систему. (Это включает в себя графические входы в систему, так как они также начинаются с оболочки входа в систему.) Если оболочка является интерактивной, пользователь, запустивший ее, вероятно, вошел в систему, и поэтому у него, вероятно, есть предок (который запустил или запустил то, что запустил ее, или начал это и т. д.) это была оболочка входа в систему.

Возможно, вы захотите выполнить команду только один раз, потому что:

  1. нет причин запускать его более одного раза за один вход в систему, это будет неэффективно или
  2. это приведет к нежелательному результату - запускать его несколько раз за вход в систему.

В качестве примера второй ситуации, когда может возникнуть нежелательный результат, рассмотрим эти строки, которые появляются по умолчанию у каждого пользователя ~/.profile:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Предположим, вы вошли в SSH, запустили другую оболочку (скажем, zsh), в какой-то момент обнаружили, что вы хотите временно вернуться к ней, bashно сохранить свою среду (поэтому bashснова запустились в то время как в zsh), а затем запустили такую ​​программу, mcкоторая запускает оболочку как часть его интерфейса. Если binсуществует в вашей домашней папке и ваше имя пользователя есть james, ваша PATHвнутренняя оболочка выглядит примерно так:

/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

Это неэффективно и (что гораздо важнее) затрудняет понимание содержания PATH.

Это ни в коем случае не катастрофа. Насколько я могу судить, если бы каждая интерактивная оболочка создавала "профильные" файлы, ничего страшного не произошло бы в конфигурации по умолчанию . Однако, поскольку цель файлов «профиля» состоит в том, чтобы содержать команды для однократного запуска при каждом входе в систему , пользователь или администратор может добавлять команды в профиль, которые должны выполняться только при запуске оболочки входа в систему.

Где разместить команды для запуска каждой интерактивной оболочки

Если вы используете bash, есть файлы для команд, которые должны выполняться в каждой интерактивной оболочке:

  • /etc/bash.bashrc
  • .bashrc в домашнем каталоге пользователя.

Это чаще всего используется для команд, которые

  1. влияют только на среду оболочки, в которой они работают, - даже на дочерние оболочки, или
  2. должен работать, даже если это не оболочка входа в систему.

Например, табуляция командной строки обычно должна быть включена независимо от того, bashбыла ли оболочка входа в систему. Так что это появляется в ~/.bashrc:

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

Там применяются 1 и 2 : это не переносится на другие оболочки, запускаемые внутри этой, и завершение табуляции должно работать, bashдаже если я вошел в систему с другой оболочкой.

Куда помещать команды для оболочек входа и интерактивных оболочек без входа в систему

Если вы используете bashи хотите, чтобы команда выполнялась в оболочках входа в систему и интерактивных оболочках и которые не являются оболочками входа в систему, обычно достаточно поместить ее в /etc/bash.bashrcили~/.bashrc . Это потому, что по умолчанию /etc/profileи ~/.profileзапускаю их явно. Например, ~/.profileимеет:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

(Точно так же /etc/profileисточники /etc/bash.bashrcдля bash.)

Таким образом, файлы «profile» и «rc» запускаются при запуске интерактивной bashоболочки (независимо от того, является ли она оболочкой входа в систему).

Где разместить команды для запуска в неинтерактивных оболочках

Вы, вероятно, не хотите указывать какие-либо команды для запуска всех неинтерактивных оболочек; они будут запускаться при каждом запуске сценария (при условии, что сценарий запускается оболочкой, настроенной для их запуска).

Это может вызвать существенную поломку. Если вы собираетесь это сделать, и в системе нет учетной записи администратора, кроме той, которую вы используете, вы можете создать ее; это может облегчить исправление ошибок.

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

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

Таким образом, если вам нужны команды для автоматического запуска даже в неинтерактивных оболочках, подобных тем, которые запускаются для выполнения сценариев, вы можете добавить свои команды перед этими строками.

Запуск Оболочки входа

Вход в систему запускает оболочку входа. Если вы хотите, чтобы оболочка, запущенная после этого, действовала как оболочка входа в систему, запустите ее с -lфлагом (означает l ogin ). Например:

Это лучший способ запустить оболочку входа в систему (без входа в систему), если вы не хотите запускать ее как другого пользователя. Затем используйте:

  • sudo -iдля root(используйте sudo -sдля интерактивной корневой оболочки без логина)
  • sudo -u username -i для любого пользователя
  • su - usernameдля не rootпользователей (используйте для не-входа, интерактивную корневую оболочку)su username

Что такое начальная оболочка для входа?

Первоначальные Войти оболочки таких же , как оболочка входа . Везде, где этот ответ говорит «оболочка входа в систему», он мог бы сказать «начальная оболочка входа в систему» ​​(кроме этого раздела, который уже перестал бы иметь смысл).

Одной из причин термина « начальная оболочка входа в систему» является то, что оболочка входа также используется в другом смысле - для определения того, какая программа используется в качестве оболочки, которая выполняется при входе в систему. В этом смысл оболочки логина :

  • « Оболочка для входа в OpenBSD по умолчанию: kshв Ubuntu это так» bash.
  • Msgstr "Вы можете изменить свою оболочку входа в систему с помощью chsh."

Дальнейшее чтение

Элия ​​Каган
источник
4
Один из лучших ответов на любой вопрос на любом сайте Stack Exchange.
Марк Э. Хаас
1
> «профильные» файлы должны содержать команды, которые должны выполняться только один раз, в начале входа в систему. (Это включает в себя графические логины, так как они также начинаются с оболочки входа в систему.) Нет, нет, нет, нет! Это абсолютно не так! Все борновоподобные оболочки читают .profile только в сеансах оболочки интерактивного входа в систему , т. Е. Те, которые были запущены с опцией -i, или те, которые подключены к управляющему терминалу (ни то, ни другое не верно, если оболочка была запущена менеджером дисплея). Причина этого заключается в том, что целью этого файла является настройка терминала пользователя , а не только его среды. Если менеджер дисплеев tr
Элия, я воспроизвел остальную часть комментария Дерека здесь, но оставил вышеупомянутый пень, чтобы он получил уведомление о вашем ответе, хотя он не сможет ответить на это из-за требований репутации. Однако я дал ему доступ для записи в вышеупомянутую комнату чата.
Сет
1
In bash, the "rc" files are actually run whether the shell is interactive or not. это неверно. /etc/bash.bashrc запускается /etc/bash.profile.
Okwap
okwap прав, rc файлы не запускаются в неинтерактивной оболочке, это более кратко и точно.
Ник Аллен