Shell脚本和编程 | 青训营笔记

47 阅读3分钟

前言

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的一种具体实现,可以理解成实例和类的关系。

构成

image.png

shell不仅提供了与内核和设备交互的方法,还集成了一些今天软件开发中通用的设计模式 (比如管道和过滤器),具备控制流程, 循环, 变量,命令查找的机制;

它既是命令解释器,也是一门编程语言,作为命令解释器,它提供给用户接口,使用丰富的GNU工具集,第三方的或者内置的,比如cd、 pwd、 exec、 test、 netstat 等等。

执行过程和原理

执行

  1. shel1脚本一般以.sh结尾,也可以没有,这是一个约定;第一行需要指定用什么命令解释器来执行

    1 #! /bin/bash

    1 #! /usr/bin/env bash

    注意:#!是内核识别并选择合适的解释器之后,将文本文件再交给解释器执行。

  2. 启动方式

1 #文件名运行
2 . /filename.sh
3
4
5 #解释器运行
6 bash ./filename.sh
7
8
9 # source运行
10 source ./filename.sh 

执行过程

image.png

  1. 字符解析

    • 识别换行符、 分号(;) 做行的分割

    • 识别命令连接符(|| &&管道)做命令的分割

    • 识别空格、tab符, 做命令和参数的分割

  2. shell 展开, 例如{1..3}解析为1 2 3

  3. 重定向, 将stdin、stdout、 stderr的文件描述符进行指向变更

  4. 执行命令

    • builtin直接执行

    • 非builtin 使用$PATH 查找,然后启动子进程执行

  5. 收集状态并返回

这个架构类似一个流水线,在里面进行输入分析和解析

bash会以一些特殊字符作为分隔符,将文本进行分段解析。最主要是回车还有分号“;”。在bash脚本中是以回车或者分号作为-行命令结束的标志。这就是第一层级的解析,将大段的命令行进行分段。

符号拓展(使用各种方法,比如大括号{}、波浪符~、 变量和参数的展开/替换、文件名展开) ,并最终执行命令(通过shell内置命令或外部命令)。

shell展开

  1. 大括号展开(Brace Expansion) {...}

  2. 波浪号展开(Tilde Expansion) ~

  3. 参数展开(Shell Parameter Expansion)

  4. 命令替换(Command Substitution)

  5. 数学计算(Arithmetic Expansion) $((..))

  6. 文件名展开(Filename Expansion) * ? [..]外壳文件名模式匹配

其他

shell脚本是不是很神奇呢,快来一起探索吧~