马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
同一个用户在 GNOME 里打开一个终端,和在 SSH 里敲一条命令,拿到的 shell 环境可能完全不一样——有的环境变量生效、有的别名没加载,原因多半出在 login shell 和 non-login shell 读的配置文件不同。本文以 Bash 为例,把两者的触发场景、判断方法和配置文件优先级讲清楚,其余 shell 同理。
一、shell 是什么,login shell 又是什么
shell 是 Linux 与外界交互的程序。登录 shell 有两种形态:login shell 与 non-login shell。二者的核心差别不是“界面好不好看”,而是启动时读取哪些配置文件,从而决定了环境变量、别名、提示符这些从哪来。
这个概念对 Bash、csh、tcsh、zsh 都适用,本文只展开 Bash。
二、哪些场景是 login shell
- 在 GNOME 等图形界面里输入用户名、密码登录后(它虽然不是命令行 shell,但仍可看作 login shell)。
- 图形界面里把「Run command as login shell」选项打开,然后右键选择 Open Terminal 打开的 bash。
- 用
Ctrl+Alt+F* 快捷键或 chvt 命令启动的终端,输入用户名和密码登录 bash(这也是 SSH 远程连接的情况)。
- 在 shell 里用
su 命令,且带 -、-l 或 --login 选项。
- 在 shell 里用
bash 命令,且带 -、-l 或 --login 选项(无论交互式还是非交互式)。
一个常见误区
很多人以为“输入了密码登录的就是 login shell,没输密码就是 non-login shell”,这是错的。第 1 项里通过图形界面登录,属于 login shell,但整个过程你并没有“登录一个 shell”的动作;反过来,在终端里执行 bash 不带 -l,会开一个 non-login shell,可你依然要输入密码的场景也可能存在。
三、哪些场景是 non-login shell
- 图形界面里没开「Run command as login shell」,直接右键 Open Terminal 打开的 bash。
- 在 shell 里用
su 命令,且不带 -、-l 或 --login。
- 在 shell 里用
bash 命令,且不带 -、-l 或 --login(交互式和非交互式都是)。
四、怎么判断自己当前是不是 login shell
方法 1:看登录提示
部分 login shell 登录时会提示上一次的登录状态和时间。有这类提示通常是 login shell,但它不是绝对判据。
方法 2:看 $0
echo $0
如果值带前导减号,比如 -bash,那是 login shell;如果是 bash、/bin/bash 这类没有前导减号的,就是 non-login shell。
这个方法在前面第 1 类(图形界面登录)和第 3 类里用 bash 命令新开的 shell 上会失效,别全信。
方法 3:看 shopt
shopt -q login_shell && echo "This is a login shell" || echo "This is a non-login shell"
开启了 login_shell 选项即表示是 login shell。同样,对图形界面登录那一种场景无效。
方法 4:自己插一个探针(最可靠)
给 /etc/profile 末尾加一行(需要 root),每次 login shell 启动时都会往日志 里写东西:
echo "This is from /etc/profile" >> /tmp/profile_test.log
之后新开一个终端看日志 有没有增长,就能确认 profile 系列文件到底有没有被读过。这个思路也可以用来排查“我设的环境变量怎么没生效”。
五、配置文件清单与优先级
下面这些文件的读取和执行,效果是类似 source 命令那样自动完成的,只是你没有显式敲过。
1. /etc/profile
- 用途:系统级别的 login shell 配置文件,对所有用户都生效。
- 执行时机:login shell 登录时执行一次。
- 内容:通常定义全系统的
$PATH、历史记录设置、默认权限掩码(umask)等,还会遍历执行 /etc/profile.d/ 目录下的其他脚本。
- 位置:在系统的
/etc 目录,是全局文件,管理员在这里做的设置会影响所有用户。
2. ~/.bash_profile
- 用途:用户级别的 login shell 配置文件,用来放这个用户专属的环境变量、别名等。
- 执行时机:Bash login shell 登录时执行。
- 内容:里面常见一句对
~/.bashrc 的 source 调用。这样一来,login shell 既跑 login 相关的设置,也会把 non-login 那套别名、提示符带进来。
3. ~/.bash_login
- 用途:另一个用户级别的 login shell 配置文件,和
~/.bash_profile 类似。
- 优先级:Bash 启动 login shell 时先找
~/.bash_profile,它不存在才尝试 ~/.bash_login。
- 说明:用得比较少,大多数用户只维护
~/.bash_profile;只有前者缺失时它才会登场。
4. ~/.profile
- 用途:通用型的用户级 login shell 配置文件,不只服务 Bash,sh 等其他 shell 也会读它,对任何 Bourne shell 派生的 shell 都适用。
- 执行时机:当
~/.bash_profile 和 ~/.bash_login 都不存在时,Bash 才会执行 ~/.profile。
- 内容:通常放用户级环境变量和启动脚本。
5. ~/.bashrc
- 用途:用户级别的 non-login shell 配置文件,放别名、自定义函数、命令提示符(PS1)等命令行习惯类设置。
- 执行时机:Bash 以交互式 non-login shell 启动时执行。
- 想让 login shell 也吃到:在
~/.bash_profile 或 ~/.profile 里显式 source 一次 ~/.bashrc,这是发行版里的常见做法。
六、完整优先级顺序
Bash 启动 login shell 时的查找顺序是:
~/.bash_profile(存在就执行,后面两个不再看)
~/.bash_login(仅当上一条不存在)
~/.profile(仅当前两条都不存在,且文件里通常会自己 source ~/.bashrc)
先读谁、后读谁、谁读到了就停,理解了这条链路,遇到“别名没生效”“环境变量只在某个终端有”这类问题,直接对照文件路径排查即可。
七、实用提醒
- 改了
~/.bashrc,当前 shell 不会自动生效,用 source ~/.bashrc 或重新开一个终端。
- 在
/etc/profile 里加东西要谨慎,它会影响所有用户,改完建议 source /etc/profile 先在本终端验证。
- 写脚本时不要依赖登录 shell 才加载的环境变量,脚本里显式 export 更稳妥,避免“手动跑没问题、crontab 里就报错”。
~/.bashrc 被 /etc/profile 的 profile.d 脚本二次 source 时容易重复叠加 PATH,写 PATH 拼接时建议用 $PATH 展开的方式,而不是从零覆盖。
八、总结
login shell 和 non-login shell 的分界就是“启动时读不读那一套登录配置文件”。判断手段上,$0 和 shopt -q login_shell 方便但各有盲区,/etc/profile 探针最可靠。配置层面记住一条链:/etc/profile → ~/.bash_profile → ~/.bash_login → ~/.profile,non-login 侧则是 ~/.bashrc,靠 ~/.bash_profile 里那句 source 把两侧串起来。把这套对应关系记牢,绝大多数“环境变量或别名莫名丢失”的问题都能一句话定位到是哪个文件没被读到。
qidao123.com企服评测-应用市场 编辑提示 |