[ 前端与 HTML | 青训营笔记 ]

108 阅读4分钟

第三节 Shell 脚本和编程

学习 shell 的价值:

  1. Linux 服务器的基本操作和管理

  2. 前端 Node.js 服务的进程管理、问题排查、资源监控等运维操作

  3. 使用 shell 编写TCE、SCM、Docker 脚本,完成服务编译和部署

一、Shell 基础概念

概念:

  • 终端:获取用户输入、展示运行结果的硬件设备
  • tty:teletypeWriter的简称,和终端等价,早期指电传印机. 在linux 中是输入/输出环境
  • 终端模拟器:Mac Terminal、 iTerm2等,关联虚拟 tty 的输入输出软件
  • Shell:command interpreter ,处理来自终端模拟器的输入,解释执行之后输出结果给终端
  • Bash:shell的—种具体实现

发展:

  • 1971 为UNIX开发第一个shell ,称V6 shell
  • 贝尔实验室为V7 UNIX开发的 Bourne shell 即sh
  • 为了取代Bourne shell开发的Bourne-Again shell即 Bash

构成:

  • 解释器:bash 内置命令、GNU核心工具集、第三方库
  • 编程语音:变量、运算、语句、函数

二、命令和语法

变量:

  • 类型:自定义变量 当前 shell 声明方式:=
  • 类型:环境变量 当前 shell 及其子 shell 声明方式:export、declare -x
  • 类型:系统环境变量 所有 shell 声明方式:启动加载

自定义变量:

declare [+/-] 选项 变量

  • 选项:- 含义:给变量设定类型属性
  • 选项:+ 含义:取消变量的类型属性
  • 选项:-a 含义:将变量声明为数组类型
  • 选项:-i 含义:将变量声明为整数型
  • 选项:-x 含义:将变量声明为环境变量
  • 选项:-r 含义:将变量声明为只读变量
  • 选项:-p 含义:显示指定变量的被声明的类型

管道:

管道与管道符|,作用是将前一个命令的结果传递给后面的命令

  • 语法:cmd1 | cmd2
  • 要求:管道右侧的命令必须能接受标准输人才行,比如l grep命令, ls、mv等不能直接使用,可以使用xargs预处理
  • 注意: 管道命令仅仅处理stdout,对于stderr会予以忽略, 可以使用set -o pipefail设置 shell遇到管道错误退出

重定向:

  1. 输出重定向符号:
  • 1)>:覆盖写入文件
  • 2)>>:追加写入文件
  • 3)2>:错误输出写入文件
  • 4)&>:正确和错误输出统一写入到文件中
  1. 输人重定向符号:
  • 1)<
  • 2)<<

判断命令:

shell中提供了test、[、[[三种判断符号,可用于:

  • 整数测试
  • 字符串测试
  • 文件测试

语法:

  • test condition
  • [ condition ]
  • [[ condition ]]

注意:

  • 中括号前后要有空格符;
  • [和l test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
  • 中括号内的变量,最好都是用引号括起来
  • [[更丰富,在整型比较中支持<、>、=,在字符串比较中支持=~正则

循环:

  • while循环 while condition ; do程序段;done
  • until循环 until condition ; do程序段;done
  • for循环 for var in [words...]; do程序段;done

函数:

语法一: funcName(){ echo "abc"; }

语法二: function funcName() { echo "abc"; }

注意:

  • shell自上而下执行,函数必须在使用前定义
  • 函数获取变量和 shell script类似,O代表函数名,后续参数通过O代表函数名,后续参数通过1、$2 ...获取
  • 函数内return 仅仅表示函数执行状态,不代表函数执行结果
  • 返回结果一般使用echo、printf,在外面使用$()、“获取结果
  • 如果没有return ,函数状态是上一条命令的执行状态,存储在$?中

模块化:

模块化的原理是在当前shell内执行函数文件,方式: source [函数库的路径]

三、执行过程和原理

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

#!/bin/bash

#!/usr/bin/env bash

2、启动方式

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

执行过程:

  1. 字符解析
  • 识别换行符、分号(:)做行的分割
  • 识别命令连接符(&&管道)做命令的分割
  • 识别空格、 tab符,做命令和参数的分割
  1. shell展开,例如{1..3}解析为123

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

  3. 执行命令

  • builtin直接执行
  • 非 builtin使用$PATH查找,然后启动子进程执行
  1. 收集状态并返回

shell展开:

  1. 大括号展开(Brace Expansion) { ...}
  • 一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分割的字符串序列,也可以是序列表达式区{x..y [..incr]}
  1. 波浪号展开(Tilde Expansion)~
  2. 参数展开(Shell Parameter Expansion)
  3. 命令替换(Command Substitution)
  4. 数学计算(Arithmetic Expansion)$((..))
  • 使用$(())包裹数学运算表达式,得到结果并替换
  1. 文件名展开(Filename Expansion) * ?[..]外壳文件名模式匹配
  • 当有单词没有被引号包裹,且其中出现了‘*’, ‘?’, and‘[’字符,则shell 会去按照正则匹配的方式查找文件名进行替换,如果没找到则保持不变。

四、调试和前端集成

调试:

  1. 普通log,使用echo、printf
  2. 使用set命令
  3. vscode debug插件

VSCode 配置:

  1. shellman:代码提示和自动补全
  2. shellcheck:代码语法校验
  3. shell-format:代码格式化
  4. Bash Debug:支持单步调试
  • 安装vscode插件
  • 编写launch.json文件
  • 升级bash到4.x 以上版本

前端集成:

  1. node中通过exec、spawn调用shell命令
  2. shell脚本中调用node命令
  3. 借助zx等库进行javascript、 shell script的融合
  • 借助shell完成系统操作,文件io、内存、磁盘系统状
  • 借助nodejs 完成应用层能力,网络io、计算等