一、登录shell与非登录shell
1.登录shell定义:指的是当用户登录系统时所取的那个shell,登录shell属于交互式shell。
登陆shell通常指的是:用户通过输入用户名/密码(或证书认证)后启动的shell.例如:
当时候图形环境登录时启动X的看不见的shell、使用su-username、su -l username、通过bash --login、bash -l命令启动bash、通过网络登录一台远程机器上时登录的shell、虚拟控制台登录shell等。
而其他情况启动的shell基本上就都是"非登陆shell"了。
例如,从图形界面启动终端(在Gnome或KDE中打开一个"终端"(terminal)窗口程序)、使用su切换用户、通过bash命令启动bash、在命令行替换中的子shell、被圆括号分组的命令使用的子shell、执行脚本时使用的shell等。
(一)登录与非登录shell的特点:
1.登录shell特点:
(1)登录shell属于交互式shell。用exit和logout皆可以退出。
2.非登录shell的特点:
例如:只能用exit退出,不能用logout退出。
注:用这个特证绝对可以区别登录和非登录shell。
(二)登陆与非登录shell的启动文件及其顺序(针对自己使用的rhel8)
1.登录shell启动文件顺序:
/etc/profile->/etc/profile.d/*.sh->~/.bash_profile->~/.bashrc->/etc/bashrc。
2.非登录shell启动文件顺序(读取配置文件顺序):
~/.bashrc ->/etc/bashrc
(三)登录shell与非登录shell的区别
1.含义:登录shell,指的是当用户登录系统时所取的那个shell,登录shell属于交互式shell。
登录shell将查找5个不同的启动文件来处理其中的命令,用户登录后,在终端上输入命令,shell立即执行用户提交的命令,当用户退出后,shell也终止了。
2.完整度不同:如果启动了一个bash shell而没有登入系统(如在CLI提示符中键入bash),则启动了一个交互式非登录shell。交互式非登录shell执行~/.bashrc文件中的命令。
3.使用情况不同:登录shell的初始化文件(比如.bash_profile)通常会运行这个文件。这样,登录shell和非登录shell都可以使用.bashrc中的命令。
4.登陆方式不同:登录 shell 需要用户名、密码登录后进入的shell,或者通过 --login 选项生成的 shell 。
非登录 shell 是指不需要输入用户名和密码即可打开的 shell,比如输入命令 bash或者sh 就能进入一个全新的非登录shell,在Gnome或KDE中打开一个 "terminal" 窗口,也是一个非登录 shell。
5.参数值不同:
查看$0的值,登录shell返回--bash,而非登录shell返回的是bash(bash --login或者bash -l进入的登录shell除外)。
注:shell --login 或者shell -l直接进入登录shell,但是echo $0的结果是bash。
需要注意的是:执行exit命令,退出的shell可以是登录或者非登录shell;执行logout命令,则只能退出登录shell,不能退出非登录shell。
注:
1.如果通过bash --login命令进入登录shell,尽管进入的登录shell,$0的值是bash,而不是-bash。
2.非登录模式表示用户在新的shell中没有登录,能执行logout的shell,一定是登录模式中。
3.`su - `相关的所有shell方式都无法继承父shell环境变量.`ssh 用户名@ip script.sh`无法继承父shell环境变量.
4.在最开始,一般情况下,用户要么通过ssh登录要么直接在本地登录,这种属于是登录式shell。
随后,在命令行下执行`su - 用户名`、`su -l username`、`bash -l`都是打开登录一个新的shell。而执行 `su 用户名`、`bash`都是打开一个新的shell,自动执行的shell脚本(没人人为输入的),但是没有登录。其中在图形界面打开命令界面也是非登录模式。
注:本条中bash的名字可以换成其他的shell的名字也可以,比如tcsh -l进入的shell是一个登录shell。
5.环境变量继承:
非登录模式会继承父shell的环境变量,而登录模式中`su - username`新打开的shell和父shell没有继承关系,所以不可以继承环境变量,但是`bash -l`可以继承父shell的环境变量。交互非登录式shell(比如`su username`命令登录的shell)继承父shell的环境变量。(注:bash -l等同于bash --login)
6.非登录shell不会执行/etc/profile,如果想获得里面的环境变量,必须执行source /etc/profile,即手动获取。
7.~/.bashrc文件中有这样一句:if [-f /etc/bashrc ]; then ./etc/bashrc fi,意思是判断/etc/bashrc文件是否存在,如果存在,则执行这个文件。所以有的书中说,~/.bashrc会运行/etc/bashrc文件。
8.登录shell和非登录shell具体会读取什么配置文件,要根据具体的系统版本而定,如RHEL6.3中非登录shell仅执行了"~/.bashrc"文件(没有执行/etc/bashrc),而Ubuntu10.04中却依次执行了/etc/bash.bashrc和~/.bashrc 文件。rhel8非登录shell则执行了~/.bashrc和/etc/bashrc两个配置文件。对于这些规则,可以直接在相应的配置文件中加一些echo命令来验证其真实性。
9.识别登录shell和非登录shell,仅在当前shell中查看 $0 的值是不可以的,因为通过bash --login(或者bash -l)命令进入的是登录shell,$0的值是bash(尽管是个登录shell)。但是登录shell一共就2种情况,情况1是$0的值为-bash一定是登录shell,情况2是通过bash --login(或者bash -l)登录到的shell一定是登录shell。
10.使用将环境放在/etc/profile.d/*.sh的脚本中,更加的方便快捷一点,这个准则是不一定的,不是所有的系统的非登录shell都会读取这些文件,比如rhel8就是如此。这个准则成立的前提是所有交互式shell都会运行/etc/profile.d/*.sh才可以。
二、交互式shell与非交互式shell
1.交互式shell:shell与用户存在交互;非交互式:即shell与用户不存在交互。非交互式,是shell的另一种运行模式,它专门被用来执行预先设定的命令。在这种模式下,shell不与用户进行交互,而是读取存放在脚本文件中的命令并执行它们。当它读到文件的结尾,这个shell就终止了。
比如,Non Interactive Shell:你需要写一个bash script,用外部shell执行"bash script.sh"命令,它(bash)从可以第一条命令执行到最后一条然后退出,不与你进行任何交互,它就是非交互式shell。
交互式非登录shell,例如你在Gnome图形界面中打开"终端"出来的那种窗口程序,和登录shell相比,它是"非登录"的,你并不需要输入用户名和密码,和非交互式shell相比,这是"交互式"的,就像你说的那它"你输入什么,它就解释什么"。
注:
1.交互、非交互模式的本质区别在于,一批任务在执行过程中,是否需要人机互动。比如执行一批任务,需要手动一个一个敲入命令,这样就是交互模式,还有在命令执行过程中,需要人为为程序输入数据,这也是交互模式,不过如果提前准备好输入,例如:`order <input.txt`不需要人为输入数据,也就变成了非交互模式。将一批任务写为一个shell脚本,虽然过程中不需要人为再输入命令,但是可能程序执行过程中需要输入参数,所以执行shell脚本这即可能是交互模式,也可能是非交互模式。
2.交互式shell举例:
(1)交互式模式就是在终端上执行,shell等待你的输入,并且立即执行你提交的命令,然后将结果反馈给你。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、退出。当你退出后,shell也终止了。
3.非交互式shell举例:
(1)脚本执行shell(不需要人为输入的)。
4.交互式shell与非交互式shell区别:读取的配置文件不同,交互式bash必然读取~/.bashrc文件;非交互式bash读取的是环境变量BASH_ENV(通常情况下)所指定的配置文件。
5.交互式shell会启动如下文件:(1)~/.bashrc(2)/etc/bashrc(~/.bashrc文件会启动/etc/bashrc)
6.交互式shell指打开了一个shell进入了一个新的命令行界面。所有的交互式shell一般都会执行~/.bashrc文件和/etc/bashrc两个文件(e.g.rhel8系统)。
7.为了更直观,给大家配置2个表格
表6-13 不同类型的bash Shell
|---------------------------|---------|----------|
| 上下文 | 登录Shell | 交互式Shell |
| 从虚拟控制台登录Shell | 是 | 是 |
| 通过网络Shell到一台远程机器上时登录Shell | 是 | 是 |
| X初始化Shell | 是 | 是 |
| X终端Shell | 否 | 是 |
| 手动运行bash启动的子Shell | 否 | 是 |
| 用在命令替换中的子Shell | 否 | 否 |
| 被圆括号分组的命令使用的子Shell | 否 | 否 |
| 命令执行脚本时使用的子Shell | 否 | 否 |
注:脚本执行有多种方式,用source或者.命令执行脚本的方式是在当前shell中获得脚本和执行脚本(即执行脚本和获得脚本是在当前shell中而非当前shell的子shell中),如果执行脚本用绝对路径、相对路径、bash命令、sh命令执行脚本,则是在当前shell的子shell中执行脚本的。下面以执行脚本,script.sh为例:
1.绝对路径执行脚本:
/home/alice/script.sh #这种方式是在子shell中执行脚本
2.相对路径执行脚本(即进入脚本所在目录,执行以下命令):
./script.sh #这种方式也是在子shell中执行脚本
3.用bash或者sh命令执行脚本
bash script.sh #子shell中执行脚本
sh script.sh #子shell中执行脚本
4.source或者.执行脚本
source script.sh #当前shell中执行脚本
. script.sh #当前shell中执行脚本
表 6-14 bash的启动配置文件
|----------------------|------------|-------------------------|
| 文 件 | Shell类型 | 预期功能 |
| /etc/profile | 登录Shell | 通用的有效环境变量 |
| /etc/profile.d/*.sh | 登录Shell | 软件包特有的环境变量 |
| ~/.bash_profile | 登录Shell | 用户特有的环境变量 |
| ~/.bashrc | 所有交互式Shell | 用户特有的别名、Shell功能和Shell选项 |
| /etc/bashrc | 所有交互式Shell | 通用别名、Shell功能和Shell选项 |