Чтение «bash_profile» выполняет две вещи, которые противоречат друг другу

#bash #shell #terminal

#bash #оболочка #терминал

Вопрос:

Я очень смущен тем, как моя оболочка читает bash_profile.

В корне мой ~/.bash_profile выглядит так

 # .bash_profile

# Get the aliases and functions
if [-f ~/.bashrc ]; then
        .~/.bashrc
fi

PATH=$PATH:$HOME/bin:$HOME/sbin:$HOME/usr/sbin:$HOME/usr/bin:/usr/sbin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

export PATH=$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
unset USERNAME
  

Файла ~/.profile нет.

У пользователя с именем maruhan мой ~/.bash_profile выглядит так

 # .bash_profile

# Get the aliases and functions
if [-f ~/.bashrc ]; then
        .~/.bashrc
fi

PATH=$PATH:$HOME/bin:$HOME/sbin:$HOME/usr/sbin:$HOME/usr/bin:/usr/sbin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/maruhan/Desktop/issac:/usr/local/lib
ASDF=$ASDF:/home

export PATH=$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
export ASDF=$ASDF
unset USERNAME
  

И мой ~/.profile выглядит так

 LD_LIBRARY_PATH=/home/maruhan/Desktop/issac:/usr/local/lib:$LD_LIBRARY_PATH
ASDF=/home:$ASDF
export ASDF=$ASDF
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
  

Вы можете ясно видеть, что ASDF не определен в корневом bash_profile.

Однако, когда я звоню export , я получаю это в root.

 declare -x ASDF=":/home"
  

но ничего о LD_LIBRARY_PATH.

Как ни странно, в maruhan запуск экспорта показывает как ASDF, так и LD_LIBRARY_PATH.

Кроме того, ничего о ASDF или LD_LIBRARY_PATH не существует в /etc/environment . У меня также нет файла /etc/bash_profile .

Запуск echo $0 дает мне bash как root, так и maruhan.

Почему LD_LIBRARY_PATH исчез в корне, а ASDF есть?

Комментарии:

1. Как запускается пользователь root bash ? И марухан ?

2. @whjm можете ли вы помочь мне, как это проверить?

3. export PATH LD_LIBRARY_PATH ASDF достаточно; вам не нужно «переназначать» значения. export отмечает имена, а не значения.

4. @chepner я знаю. Я не был уверен на 100%, и все шло не так, как задумывалось, поэтому я поместил его туда на всякий случай.

5. @CuriousKimchi — Обновил мой ответ.

Ответ №1:

Правила немного сложны. Согласно справочной странице bash:

ВЫЗОВ

Оболочка входа — это оболочка, первый символ нулевого аргумента которой равен a - , или оболочка, начинающаяся с --login параметра.

Интерактивная оболочка — это оболочка, запущенная без параметров, не являющихся параметрами (если -s не указано), и без -c опции, стандартный ввод и ошибка которой подключены к терминалам (как определено isatty(3) ), или одна, запущенная с -i опцией. PS1 устанавливается и $- включает i , является ли bash интерактивным, позволяя сценарию оболочки или файлу запуска проверять это состояние.
… …
Когда bash вызывается как интерактивная оболочка входа или как неинтерактивная оболочка с --login опцией, она сначала считывает и выполняет команды из файла /etc/profile , если этот файл существует. После чтения этого файла он ищет ~/.bash_profile , ~/.bash_login , и ~/.profile , в таком порядке, и считывает и выполняет команды из первого, который существует и доступен для чтения. --noprofile Опция может использоваться при запуске оболочки, чтобы запретить это поведение.
… …
Когда запускается интерактивная оболочка, которая не является оболочкой входа, bash считывает и выполняет команды из ~/.bashrc , если этот файл существует. Это может быть заблокировано с помощью --norc опции. Опция --rcfile file заставит bash считывать и выполнять команды из file вместо ~/.bashrc .
… …

Обратите внимание, что в некоторых системах bash может быть настроен так, чтобы он также выполнял общесистемный rc-файл (например /etc/bash.bashrc ) перед ~/.bashrc поиском интерактивной оболочки, которая не является оболочкой входа.

Оболочки, запускаемые механизмом входа в систему (обычно с запросом имени пользователя / пароля, например, console login, telnet , ssh , …), обычно являются оболочками входа в систему. Для оболочки входа $0 в систему обычно -bash .

 [local] % ssh user@host  <-- The user is trying to login
Password: P@ssw0rd
[remote] % echo $0
-bash                    <-- This is a login shell
[remote] % bash          <-- This is not a login (no username/password)
[remote] % echo $0
bash                     <-- Not a login shell
[remote] %
  

Чтобы упростить жизнь, я бы вставил все rc-вещи ~/.bashrc и исходный ~/.bashrc ~/.bash_profile код. Например:

 % cat ~/.bash_profile
[[ -f ~/.bashrc ]] amp;amp; source ~/.bashrc
% cat ~/.bashrc
# return immediately if not in an interactive shell
[[ $- != *i* ]] amp;amp; return 0

export FOO=bar
PATH=$PATH:/my/path
%