一、Shell 的类型
Shell 是用户与操作系统内核交互的接口程序,常见的 Shell 类型包括:
• Bash(Bourne Again Shell):Linux 默认 Shell,功能强大,支持脚本、别名、历史命令等。
• Sh(Bourne Shell):早期 Unix Shell,功能较基础。
• Csh / Tcsh:语法类似 C 语言,适合交互式使用。
• Zsh:增强型 Shell,支持插件、主题、自动补全等,macOS 默认。
• Ksh(Korn Shell):兼容 Bourne Shell,增加部分 Bash 特性。
实践操作:
二、理解 Shell 进程及其关系
Shell 本身是一个进程,当用户登录系统时,系统会启动一个登录 Shell(如 bash),该 Shell 会:
• 读取配置文件(如 ~/.bashrc, /etc/profile)
• 启动子进程执行命令(如 ls, cp, vim)
• 子进程结束后,控制权交还父 Shell
关键概念:
• 父进程:启动当前 Shell 的进程(如终端模拟器或登录程序)
• 子进程:由 Shell 启动执行命令的进程(如 ls 是 bash 的子进程)
• 前台/后台进程:前台进程占用终端,后台进程可并行执行
实践操作:
三、Shell 的父子关系
Shell 支持嵌套执行,即在一个 Shell 中启动另一个 Shell(如 bash 或 sh),形成父子关系。
• 父 Shell 启动子 Shell,子 Shell 继承父 Shell 的环境变量(部分)
• 子 Shell 退出后,回到父 Shell
• 子 Shell 中修改的环境变量不会影响父 Shell(除非使用 export)
实践操作:
四、Shell 的运行模式
Shell 有几种主要运行模式:
- 交互式模式(Interactive):用户输入命令后立即执行,有提示符(如 $ 或 #)
- 非交互式模式(Non-interactive):执行脚本文件,无提示符,常用于自动化任务
- 登录模式(Login):用户首次登录系统时启动,读取 /etc/profile 和 ~/.bash_profile
- 非登录模式(Non-login):如打开新终端窗口,通常只读取 ~/.bashrc
实践操作:
五、内建命令和外部命令
- 内建命令(Built-in Commands)
• 由 Shell 自身实现,不创建新进程
• 执行速度快,可直接操作 Shell 内部状态
• 常见内建命令:cd, pwd, echo, history, alias, export, set, unset
- 外部命令(External Commands)
• 独立的可执行程序,位于 $PATH 路径下
• 执行时会创建新进程(fork + exec)
• 常见外部命令:ls, cp, grep, vim, top
实践操作:
六、内建命令 history 和 alias 的用法
- history 命令
• 用途:查看当前用户执行过的命令历史记录
• 默认保存在 ~/.bash_history 文件中(会话结束才写入)
• 常用参数:
• -a:将当前会话的历史追加到 .bash_history
• -c:清空当前会话历史(不删除文件)
• -n:从 .bash_history 读取未读历史到当前会话
• -r:读取 .bash_history 并覆盖当前会话历史
• -w:将当前会话历史写入 .bash_history(立即保存)
练习题 1:查看 history 和 cat .bash_history 输出有什么不同?
练习题 2:执行 history -a 后 cat .bash_history 输出有什么变化?
注意:history 显示的是内存中的历史,~/.bash_history 是磁盘文件,两者不同步直到执行 -a 或退出会话。
- alias 命令
• 用途:为常用命令创建别名,简化输入
• 语法:alias 别名=‘原命令’
• 临时生效:仅在当前会话有效
• 永久生效:写入 ~/.bashrc 或 ~/.bash_aliases
实践操作:
七、建立自己的知识框架体系
1、Shell 是什么
Shell 是用 C 语言编写的用户与 Linux 内核之间的桥梁。它既是命令语言,也是程序设计语言。我们平时输入的 ls、cd等命令,都是通过 Shell 传递给内核去执行的。以 .sh结尾的文件就是 Shell 脚本,是一系列 Shell 命令的集合。
2、Shell 的类型
Linux 中常见的 Shell 有多种,最基础的是 Bourne Shell(/bin/sh),而目前最主流、也是大多数 Linux 发行版默认使用的是 Bash(Bourne Again Shell,/bin/bash)。除此之外,还有 C Shell(/bin/csh)、K Shell(/bin/ksh)等。
系统会给每个用户指定一个默认 Shell,这个信息记录在 /etc/passwd文件的第 7 个字段中。比如 /bin/bash就表示默认使用 Bash。在 Ubuntu 等系统中,/bin/sh通常是一个指向 /bin/dash的软链接,dash是一个更轻量的 POSIX 兼容 Shell,启动速度更快,但功能不如 Bash 丰富。
可以通过 cat /etc/passwd | grep 用户名查看当前用户的默认 Shell,也可以通过直接执行 /bin/dash等命令临时切换 Shell,输入 exit即可退出。
3、Shell 的父子关系
当你通过 SSH 登录系统,或者在图形界面中打开一个终端时,系统为你启动的第一个 Shell 就是父 Shell。在这个父 Shell 中输入 bash命令,就会创建一个新的 Shell 进程,这就是子 Shell。
每一个进程在系统中都有一个唯一的 PID(进程 ID),同时还有一个 PPID(父进程 ID)。通过 ps -f命令可以看到这些信息:子 Shell 的 PPID 正好等于父 Shell 的 PID。
可以使用 ps --forest命令以树状结构直观地看到 Shell 的层级关系。每执行一次 bash,就多一层子 Shell;每执行一次 exit,就退出当前层级的 Shell,回到上一层。只有当最后一个 Shell(父 Shell)退出时,SSH 连接才会断开。
4、Shell 的运行模式
Shell 提供了多种灵活的运行模式,这也是子 Shell 的典型应用场景。
- 命令列表与进程列表
在一行中输入多个命令,用分号 ;隔开,这就是命令列表,但这些命令仍在当前 Shell 中执行。如果将这一组命令用括号 ()括起来,就变成了进程列表,系统会创建一个子 Shell 来专门执行这些命令。
可以通过环境变量 $BASH_SUBSHELL来判断是否创建了子 Shell:返回值为 0 表示没有子 Shell,返回值大于 0 则表示子 Shell 的嵌套层数。 - 后台模式
在命令末尾加上 &符号,命令就会进入后台模式执行。这样命令在运行的同时,终端仍然可以接受你的其他输入,不会被阻塞。常用 ps -f或 jobs命令查看后台进程的状态。当后台任务完成时,终端会提示 Done。 - 协程(Coproc)
使用 coproc命令可以在后台创建一个子 Shell,并在其中执行指定的命令。默认情况下,协程的名字是 COPROC,也可以通过扩展语法自定义名字,例如 coproc My_Job { sleep 10; }。注意花括号前后的空格和结尾的分号是必须的。
五、内建命令与外部命令
这是理解 Shell 执行效率的关键。 - 外部命令
外部命令是独立于 Shell 存在的程序文件,通常存放在 /bin、/usr/bin等目录中,例如 ps、ls(在某些系统中)。当执行外部命令时,Shell 会创建一个子进程来运行它,这个过程称为 fork(衍生)。因为涉及创建新进程和环境切换,外部命令的执行速度相对较慢。
可以使用 which或 type命令来查看命令的类型和所在路径。 - 内建命令
内建命令是 Shell 程序本身的一部分,编译时就嵌入在 Shell 内部。执行内建命令时不需要创建子进程,直接在当前的 Shell 进程中运行,因此执行速度更快,效率更高。常见的内建命令有 cd、exit、echo、pwd、history、alias等。
有些命令比较特殊,既有内建版本也有外部版本(如 echo和 pwd)。使用 type -a 命令名可以查看该命令的所有实现。
六、核心内建命令详解 - history:命令历史管理
history命令用于查看和管理曾经执行过的命令。它体现了 Shell 的记忆功能。
存储机制:命令历史默认存储在内存中,只有在当前 Shell 退出(如关闭终端)时,才会被一次性写入到用户主目录下的隐藏文件 ~/.bash_history中。
实时差异:history命令查看的是内存中的实时历史,而 cat ~/.bash_history查看的是上次退出 Shell 时保存的历史。因此,刚执行的命令通常只能通过 history看到。
强制写入:使用 history -a可以将当前内存中的历史命令立即追加写入到 .bash_history文件中,无需等待退出。
调用历史:输入 !!可以快速执行上一条命令;输入 !编号可以执行 history列表中对应编号的命令。 - alias:命令别名
alias允许为复杂的命令或常用参数组合定义一个简短的别名,极大提高输入效率。
设置别名:使用 alias 别名=‘原命令’,例如 alias ll=‘ls -alF’。
查看别名:直接使用 alias或 alias -p可以查看当前已生效的所有别名。
作用范围:别名只在定义它的 Shell 进程中有效。如果希望别名在每次登录时都自动生效,需要将其写入 ~/.bashrc配置文件中,并使用 source ~/.bashrc使其立即生效。
取消别名:使用 unalias 别名可以临时删除一个别名。
八、总结
通过本次学习,我系统掌握了 Shell 的类型、进程模型、运行模式、命令分类,特别是内建命令 history 和 alias 的实际用法。在 Xshell 中反复操作后,我对 Shell 的工作机制有了更直观的理解,也建立了自己的知识框架,便于后续深入学习和脚本编写。