Shell 脚本和编程 (Part 2) | 青训营笔记

54 阅读2分钟

第二部分~

执行过程和原理

执行

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

#! /bin/bash

#! /usr/bin/env bash

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

  1. 启动方式
  • 文件名运行

./filename.sh

  • 解释器运行

bash ./filename.sh

  • source 运行

source ./filename.sh

执行过程

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

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

  3. 执行命令

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

这个架构就像一个流水线,可以在里面进行输入分析和解析

image (16).png

bash 会以一些特殊字符作为分隔符,将文本进行分段解析。最主要是回车还有分号";"。

在 bash 脚本中,用回车分号作为一行命令结束的标志。这就是第一层级的解析,将大段的命令行进行分段。

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

Shell 展开

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

一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分隔的字符串序列,也可以是序列表达式 {x..y[..incr]}

image (17).png

波浪号展开 (Tilde Expansion) ~

image (18).png

参数展开 (Shell Parameter Expansion) ${}

  1. 间接参数扩展 ${!parameter},其中引用的参数并不是parameter而是parameter的实际的值

  2. 参数长度${#parameter}

  3. 空参数处理

${parameter:-word} # 为空替换

${parameter:=word} # 为空替换,并将值赋给$parameter变量

${parameter:?word} # 为空报错

${parameter:+word} # 不为空替换

  1. 参数切片

${parameter:offset}

${parameter:offset:length}

  1. 参数部分删除

${parameter%word}# 最小限度从后面截取word

${parameter%%word}# 最大限度从后面截取word

${parameter#word}# 最小限度从前面截取word

${parameter##word}# 最大限度从前面截取word

image (19).png

命令替换 (Command Substitution)

在子进程中执行命令,并用得到的结果替换包裹的内容,形式上有两种:$(...)...

image (20).png

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

使用 $(()) 包裹数学运算表达式,得到结果并替换

image (21).png

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

当有单词没有被引号包裹,且其中出现了 '*','?', '[' 字符,则 shell 会去按照正则匹配的方式查找文件名进行替换,如果没找到则保持不变。

image (22).png

调试和前端集成

调试

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

image (23).png

VSCode 配置

  1. shellman: 代码提示和自动补全

  2. shellcheck: 代码语法校验

  3. shell-format: 代码格式化

  4. Bash Debug: 支持单步调试

  • 安装vscode插件
  • 编写launch. json文件
  • 升级bash到4.x以上版本

前端集成

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