前言
Shell是一种命令行界面,也是一种编程语言, 熟练掌握 Shell 能够大大提升 Unix/Linux环境下的工作效率。本课程将从其发展历史、基础语法开始,通过示例逐步深入,不仅帮助大家学会使用 Shell ,也在一定程度上去理解 Shell 的执行原理和语法设计。本节课的内容主要包括以下几个方面:
- shell 基础和语法
- shell 执行过程和原理
- shell 调试和前端集成
Shell基础概念
概念
- 终端:获取用户输入、展示运算结果的硬件设备
- 终端模拟器:Mac Terminal、iTerm2等, 关联虚拟tty的输入输出软件
- tty:teletypeWriter的简称,和终端等价,早期指的是电传打印机,在Linux中是输入/输出环境
- Shell:command interpreter,处理来自终端模拟器的输入,解释执行之后输出结果给终端
- Bash:shell的一种具体实现
物理终端=>软件终端ty=>终端模拟器=> shell
tty或者说终端最开始指的是获取用户输入并输出的物理设备,比如电传打字机;
在linux中是接收用户输入、输出结果的终端仿真软件,比如我们用的mac terminal、iterm2等, 更强输入辅助功能、画面绘制输出的模拟终端器;
而tty变成一个虚拟概念,是linux的一个程序,每个终端模拟器关联一个虚拟tty,和内核打交道。我们可以在终端模拟器中输入tty查看关联到的虚拟tty;
bash是shell的一种具体实现,可以理解成实例和类的关系。
构成
shell不仅提供了与内核和设备交互的方法,还集成了一些今天软件开发中通用的设计模式 (比如管道和过滤器),具备控制流程, 循环, 变量,命令查找的机制;
它既是命令解释器,也是一门编程语言,作为命令解释器,它提供给用户接口,使用丰富的GNU工具集,第三方的或者内置的,比如cd、 pwd、 exec、 test、 netstat 等等。
执行过程和原理
执行
-
shel1脚本一般以.sh结尾,也可以没有,这是一个约定;第一行需要指定用什么命令解释器来执行
1 #! /bin/bash
1 #! /usr/bin/env bash
注意:
#!
是内核识别并选择合适的解释器之后,将文本文件再交给解释器执行。 -
启动方式
1 #文件名运行
2 . /filename.sh
3
4
5 #解释器运行
6 bash ./filename.sh
7
8
9 # source运行
10 source ./filename.sh
执行过程
-
字符解析
-
识别换行符、 分号(;) 做行的分割
-
识别命令连接符(|| &&管道)做命令的分割
-
识别空格、tab符, 做命令和参数的分割
-
-
shell 展开, 例如{1..3}解析为1 2 3
-
重定向, 将stdin、stdout、 stderr的文件描述符进行指向变更
-
执行命令
-
builtin直接执行
-
非builtin 使用$PATH 查找,然后启动子进程执行
-
-
收集状态并返回
这个架构类似一个流水线,在里面进行输入分析和解析
bash会以一些特殊字符作为分隔符,将文本进行分段解析。最主要是回车还有分号“;”。在bash脚本中是以回车或者分号作为-行命令结束的标志。这就是第一层级的解析,将大段的命令行进行分段。
符号拓展(使用各种方法,比如大括号{}、波浪符~、 变量和参数的展开/替换、文件名展开) ,并最终执行命令(通过shell内置命令或外部命令)。
shell展开
-
大括号展开(Brace Expansion) {...}
-
波浪号展开(Tilde Expansion) ~
-
参数展开(Shell Parameter Expansion)
-
命令替换(Command Substitution)
-
数学计算(Arithmetic Expansion) $((..))
-
文件名展开(Filename Expansion) * ? [..]外壳文件名模式匹配
其他
shell脚本是不是很神奇呢,快来一起探索吧~