一、命令解释器(The Interpreter):
在Linux/Unix系统中,或者说从狭义的角度理解,Shell是用户与Linux内核之间的命令解释器,它接收用户输入的命令,解析后传递给内核执行,并将结果返回给用户。具体来说,Shell是一个用 C 语言写出来的真实的可执行程序(比如 /bin/bash 或 /bin/zsh)。Linux 的内核(Kernel)只懂机器语言(0和1)。Shell 接收输入的命令(比如 ls),把它翻译成内核能听懂的系统调用去执行,然后再把将命令执行的结果返回并最终显示在屏幕上。
二、系统的“外壳” (The System Shell)
用户 → Shell → Kernel → 硬件
shell不是内核中的一个模块,而是运行在内核之上,如果不只是Linux而是从所有操作系统的从宏观角度看,在内核外,所有与用户交互的程序集合,包括命令行界面和图形界面,统称为“壳”(Shell)。

三、Shell脚本 (Shell Scripting Language)
一种解释型语言,即通过解释器一边读代码一边执行,方便修改调试。其他常见的解释型语言有Python、JavaScript、Ruby、PHP等。
而另一种编译型语言运行前必须“编译一次”,先整体翻译成机器代码再运行。编译后的机器码直接由CPU执行,速度快。其他常见的编译型语言有C、C++、Go、Rust等。
四、错误的概念:"shell终端"
在Linux中,Shell和终端有关联,但完全不是一回事。当打开一个终端程序时,它会启动一个shell进程(如Bash),用户在终端中输入的命令实际上是由这个shell进程解释执行的。
有以下几种常见的容易使人混淆困惑的表述:
"shell终端" :shell不是终端的一部分,而是终端中运行的程序
"在终端中执行shell命令" :准确来说是在终端中运行命令,这些命令由shell解释执行。终端本身无法执行命令,它只是运行shell的环境
"终端是命令行界面":命令行界面是shell提供的功能,不是终端本身,终端是运行命令行界面的程序
登录/非登录Shell、当前Shell、子Shell
这里的Shell指的都是命令解释器
是否为登录Shell主要看密码:输入了密码进来的就是登录 Shell,直接弹出来的就是非登录 Shell。它们的区别在于读取哪个配置文件。
输入echo $0 如果输出的是-bash说明是登录shell,如果输出的是bash则说明是非登录Shell
登录 Shell:加载了完整环境配置文件/初始化环境的 Shell
图形化界面/字符界面输入密码登录
通过 SSH 远程连接到服务器(输入了密码)。
按 Ctrl+Alt+F3 切到纯黑底白字的物理终端,输入账号密码登录。
输入
su - 用户名彻底切换身份。登录Shell触发的变量文件(触发顺序由上至下):
/etc/bashrc
/etc/profile
~username/.bashrc
~username/.bash_profile
非登录Shell:复用了父进程环境变量/局部初始化的 Shell
在图形桌面里双击打开了一个“终端”窗口。
在终端里敲了一个 bash 命令,又开了一个 Shell
输入
su 用户名切换用户非登录Shell触发的变量文件:
/etc/bashrc
~username/.bashrc
其中,/etc/bashrc和/etc/profile 是全局变量文件,而~username/.bashrc 和
~username/.bash_profile 是用户的变量文件
通过两者对比可以得出结论:
不管是登录shell还是非登录shell,如果想要指定用户触发变量文件的内容的话,写入~username/.bashrc文件
不管是登录shell还是非登录shell,如果想要系统所有的用户都生效的话,写入/etc/bashrc文件
补充:用户的登出shell触发的变量文件是~username/.bash_logout
当前Shell:接收你当前键盘输入指令的那个 Bash Shell进程。
子 Shell:是继承当前 Shell 环境的副本,但在其中执行的命令所产生的变量赋值和环境改变,不会影响父 Shell 环境。意义是变量和操作不会互相干扰。
常见的产生子Shell的场景(都属于非登录Shell):
在当前终端输入
bash命令管道符右侧的操作,如
ls | grep txt通过直接执行的方式运行一个脚本
./script.sh圆括号组内的所有命令在子 Shell 执行,不影响主Shell
(cd /tmp; ls)命令放入后台执行
sleep 100 &