概述
0号/1号和2号进程
1 | UID PID PPID C STIME TTY TIME CMD |
系统启动后,当用户登录到系统时,系统将启动一个用户态的shell进程。在shell进程中运行shell脚本程序时,系统将创建一个子shell,此时系统中将有两个shell,一个是登录时系统启动的shell,另一个是系统为运行脚本程序创建的shell。脚本执行运行完后,子shell将终止,并返回到执行脚本之前的shell。
tty终端的shell进程如下:
通过ssh连接到系统的shell进程如下:
1 | [root@localhost ~]# echo $$ |
shell分类
交互式shell与非交互式shell
区分方法
可以通过打印“$-”变量的值(代表着当前shell的选项标志),查看其中的“i”选项(表示interactive shell)来区分交互式与非交互式shell。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19[root@localhost ~]# echo $$
31991
[root@localhost ~]# cat test.sh
echo $-
case "$-" in
*i*) echo This shell is interactive;;
*) echo This shell is not interactive;;
esac
[root@localhost ~]# bash test.sh
hB
This shell is not interactive
[root@localhost ~]# echo $$
31991
[root@localhost ~]# bash -i test.sh
himB
This shell is interactive
[root@localhost ~]# echo $$
31991通过检查
$PS1
的内容是否为空判断,在非交互式shell中不会设置该变量1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21[root@localhost ~]# echo $$
31991
[root@localhost ~]# cat test.sh
echo $-
if [[ -z "$PS1" ]];then
echo This shell is not interactive
else
echo This shell is interactive
fi
[root@localhost ~]# bash test.sh
hB
This shell is not interactive
[root@localhost ~]# echo $$
31991
[root@localhost ~]# bash -i test.sh
himB
This shell is interactive
[root@localhost ~]# echo $$
31991
[root@localhost ~]# echo $-
himBH
交互式shell
顾名思义,shell等待用户输入,输入后系统立即执行并返回结果,并等待一下此输入。当退出后,shell也终止了。
启动交互式shell的方法
启动shell时不带任何选项参数
启动shell时指定-i选项参数
启动shell时指定了-s且没有指定-c参数
非交互式shell
通常情况下,执行shell脚本文件时的子shell都是属于非交互式的。在这种场景下,shell读取存放在脚本文件中的内容然后执行,直到读到文件的结尾EOF,shell终止。
登录shell与非登录shell
登录式shell
需要用户名和密码登录后才能进入的shell,或者通过–login选项打开的shell。
非登录式shell
不需要输入用户名和密码即可打开的Shell,例如:直接命令“bash”就是打开一个新的非登录shell,在Gnome或KDE中打开一个“终端”(terminal)窗口程序也是一个非登录shell。
执行exit命令,退出一个shell(登录或非登录shell);执行logout命令,退出登录shell(不能退出非登录shell)
1 | [root@localhost ~]# echo $$ |
bash是 login shell 时,其进程名为"-bash" 而不是"bash"
1 | [root@localhost ~]# echo $$ |
shell分类组合情况
登录式 | 非登录式 | |
---|---|---|
交互式 | 1.登录系统时获得的顶层shell,无论是通过本地终端登录,还是通过网络ssh登录 2.使用bash –login命令启动的shell 3.使用su [-/-l/–login] [user]切换到其他用户时 |
1.使用bash命令启动的shell 2.使用su [user]切换到其他用户时 |
非交互式 | 在脚本中使用–login选项调用bash(比如在脚本第一行做如下指定:#!/bin/bash –login) | 通常情况下执行bash脚本时运行脚本的子shell |
bash启动时执行的启动文件
登录式 | 非登录式 | |
---|---|---|
交互式 | 如果/etc/profile存在,则首先执行该文件依次查找 存在并可读的~/.bash_profile, ~/.bash_login, ~/.profile中的第一个执行如果启动时指定了 --noprofile 选项,则不执行上述两个步骤退出时,如果~/.bash_logout存在则执行 |
如果~/.bashrc存在则执行 如果指定了 --norc 参数则不执行上述步骤可以通过指定 --rcfile file 指定其他文件替代~/.bashrc |
非交互式 | 同上 | 查找环境变量BASH_ENV,读取并执行BASH_ENV指向的文件中的内容 |
shell启动选项参数
-i 选项
强制子shell使用交互式方式运行
-c cmd_string 选项
表示子shell从字符串中读入命令,如果字符串后还有变量就被设定为从$0开始的位置参数
1 | [root@localhost ~]# /bin/bash -c 'echo hello world' |
-s 选项
如果指定-s
参数,那么表示子shell从标准输入中读入命令,直到输入exit。 该参数允许指定位置参数并将其传入子shell中。
1 | [root@localhost ~]# echo $$ |