Total Pageviews

Friday 24 August 2018

login shell和non-login shell

常见Linux发行版的默认shell都是bash. 当启动一个bash时, bash会尝试读取某个配置文件, 可能的配置文件有: ~/.bash_profile~/.bash_login~/.profile 以及~/.bashrc. 但实际上bash自己只读取其中的一个配置文件, 依照的原则是:
如果是login shell, 则 依次 查找~/.bash_profile~/.bash_login 和 ~/.profile, 找到任意一个并执行其中的命令, 且不再查找后续可能的配置文件. 伪代码:
# for login interactive shell
source /etc/profile
IF ~/.bash_profile exists THEN
    source ~/.bash_profile
ELSE
    IF ~/.bash_login exist THEN
        source ~/.bash_login
    ELSE
        IF ~/.profile exist THEN
            source ~/.profile
        END IF
    END IF
END IF
如果是non-login shell, 则查找~/.bashrc文件. 伪代码:
# for none-login interactive shell
source /etc/bash.bashrc
IF ~/.bashrc exist THEN
    source ~/.profile
END IF
这里通俗解释下login shellnon-login shell:
login shell: 当你通过账号密码登录一个linux服务器时, 就是login shell;
non-login shell: 当你在登录linux服务器后, 在登录后的shell环境中执行bash命令, 进入的bash shell就是non-login shell(因为没用账号密码登录). 另外当你登录一个图形界面的linux系统时, 在图形界面打开的shell(Terminal)也是non-login shell(因为也没用账号密码登录).
那么login shellnon-login shell的不同有什么影响 ?
在linux系统使用中, 很可能需要修改shell某些环境变量(常见如改PS1变量)或添加一些自定义功能(增加lll命令等).
这里就遇到问题了, 我们的改动需要更新到两个文件中(因为他们读取的配置文件不同) !
当然, 实际上我们并没有这么做, 那怎么解决的 ? 以Debian的方法为例, 其他发行版都大同小异.
Debian中, 一个账号下通常存在.profile.bashrc两个配置文件, 分别对应login shellnon-login shell. 如果要增加自定义功能, 只需要将相应的代码添加在.bashrc中即可, 这时候non-login shell遍可以正常工作, 同时login shell也是正常的, 因为.profile文件中有这么一段代码:
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
.profile文件中尝试执行了.bashrc中的内容, 所以login shell也能够正常工作.
一个特殊的non-login shell: 当我们在shell中使用su命令切换用户时(可能需要输入密码), 默认情况下切换用户后的shell也是non-login shell. 但是我们可以通过su -命令使得切换后的shelllogin shell. 因为su --help帮助信息说道:
Usage: su [options] [LOGIN]

Options:
  -, -l, --login                make the shell a login shell`
最后, 上面说到的login shellnon-login shell全称是interactive login shellinteractive non-login shell, 关于interactivenon-interactive的区别, 有兴趣的可以自行查找资料!
参考资料:
Execution sequence for .bash_profile, .bashrc, .bash_login, .profile and .bash_logout
6.2 Bash Startup Files
------------------------------

.bashrc和.bash_profile的区别
.bash_profile会用在login shell
.bashrc 使用在interactive non-login shell

Bash下每个用户都可以配置两个初始文件:.bash_profile和.bashrc,文件存储在~根目录中。man bash中的相关解释如下:

,----------------------------------------------------------------------------
| ~/.bash_profile
| The personal initialization file, executed for login shells
| ~/.bashrc
| The individual per-interactive-shell startup file
`----------------------------------------------------------------------------

* 每次bash作为login shell启动时会执行.bash_profile。

* 每次bash作为普通的交互shell(interactive shell)启动时会执行.bashrc

* 注意
1)在shell脚本中“#!/usr/bin/bash”启动的bash并不执行.bashrc。因为这里的bash不是interactive shell。

2)bash作为login shell(login bash)启动时并不执行.bashrc。虽然该shell也是interactive shell,但它不是普通的shell。

* 一般.bash_profile里都会调用.bashrc

尽管login bash启动时不会自动执行.bashrc,惯例上会在.bash_profile中显式调用.bashrc。所以在你的.bash_profile文件中,很可能会看到如下的代码片段:
  1. if [ -f ~/.bashrc ]; then
  2. . ~/.bashrc
  3. fi

.bashrc 使用在interactive non-login shell。意思是你每次运行一个bash脚本的话,.bashrc就会被执行一次。有个简单的方法,你在.bash_profile和.bashrc里都用echo打印点东西。,就可以看到着两个文件都是什么时候被执行的了。

编辑/etc/profile修改全局环境变量
编辑.bash_profile修改当前用户的环境变量
修改完成之后source一下即可生效,例如source ~/.bash_profile

No comments:

Post a Comment