一、Shell的类型
概念理解
Shell是用户与Linux内核之间的交互接口程序,系统存在多种不同版本的Shell,各自语法、特性略有区别。
1. bash:目前Linux系统最通用、默认使用的Shell,功能完善。
2. sh:早期标准Shell,很多系统中是bash的兼容模式。
3. 除此之外还有csh、tcsh、ksh等其他Shell类型。
我们可以查看系统中所有可用Shell程序,也可以查看当前正在使用的Shell。不同Shell之间脚本语法存在少量不兼容,写脚本一般推荐使用bash。
二、理解Shell进程及其关系
概念理解
每打开一个终端窗口,系统都会启动一个独立的Shell进程,进程拥有唯一PID编号。操作系统依靠进程来执行程序。
当Shell执行一条指令时,根据命令类型行为不同:内建命令直接在当前Shell进程内部执行;外部命令会创建新的子进程去运行程序。所有进程都拥有父进程,操作系统最初的init/systemd进程是所有进程的祖先。我们可以通过查看进程列表观察当前所有正在运行的Shell进程。
三、Shell的父子关系
概念理解
Shell父子进程是Linux进程树中的层级关系。
1. 登录Shell:登录系统时创建的顶层父Shell进程。
2. 子Shell:由父Shell衍生出来的新Shell进程。当执行脚本、使用括号组合命令时,会生成子Shell。
父子Shell有明确的特性:父Shell中定义的普通变量,默认无法直接被子Shell读取;而环境变量可以传递给子Shell。子Shell运行结束后会自动销毁,不会反过来影响父Shell的变量与运行状态。子Shell退出时会向父Shell返回一个退出状态码。
四、Shell的运行模式
Shell分为两大类运行模式:交互模式、非交互模式。
1. 交互模式:我们平时Xshell、终端手动输入命令的模式。Shell会给出命令提示符,等待用户输入,逐行执行指令,支持命令补全、历史命令、别名等交互功能。登录Shell属于一种特殊的交互Shell。
2. 非交互模式:Shell自动执行脚本文件的模式,没有命令提示符,不需要人工输入,运行结束Shell立刻退出。我们编写.sh脚本运行时,就启动了非交互Shell。
两种模式加载的配置文件有区别,交互登录Shell、交互非登录Shell、脚本非交互Shell读取的环境配置文件各不相同,这会影响变量、别名是否生效。
五、内建命令和外部命令
概念区分
1. 内建命令:命令逻辑直接嵌入Shell程序内部,不需要去磁盘调用外部程序。执行时直接在当前Shell进程内部运行,不会创建子进程,执行速度更快。cd、echo、history、alias都属于内建命令。
2. 外部命令:独立存放在磁盘上的可执行程序。每次运行都会创建新的子进程去加载程序,执行速度相对慢。ls、cat、mkdir都属于外部命令。
我们可以使用专门指令来判断一条命令属于内建还是外部命令。有些名字相同的命令,系统会优先执行内建命令。
六、内建命令history的用法
用途
history用于记录、查看、管理当前用户执行过的所有历史命令,Shell会自动把历史命令保存在用户家目录的历史文件中,退出终端后依然可以保存。
主要参数功能
不带参数:列出全部历史命令并附带编号。
-c:清空内存中当前会话的历史命令记录。
-w:把内存里本次会话的历史命令写入历史文件永久保存。
-r:把历史文件里的命令重新读取到当前会话的内存中。
可以搭配数字参数,只展示最近N条命令;也可以通过历史编号快速重复执行某一条旧命令。
七、内建命令alias的用法
用途
alias用于给较长的命令自定义简短别名,简化日常输入,属于Shell内建功能,仅在当前Shell会话临时生效。
主要用法
不带参数:查看当前已经定义好的所有别名。
自定义别名:建立简短名称和完整命令的映射,方便快速输入复杂指令。
unalias:用来删除已经设置好的别名;unalias -a可以一次性清空所有自定义别名。
如果想要别名永久生效,需要写入Shell配置文件,否则关闭终端后别名就会消失。