Shell 脚本和基础
概念
变量
| 类型 | 作用域 | 声明方式 | 规范 |
|---|---|---|---|
| 自定义变量 | 当前shell | = | 字符串、整型、浮点型、日期型 |
| 环境变量 | 当前shell及其子shell | export、declare -x | |
| 系统环境变量 | 所有shell | 启动加载 |
父子进程
配置文件加载
运算符和引用
管道
将前一个命令的结果传递给后面的命令
语法:
cmd1 | cmd2
要求:管道右侧的明朗了必须能接受标准输入才行,比如grep命令,ls、mv等不能直接使用,可以使用xargs预处理
重定向
输出重定向符号:
>: 覆盖写入文件
>>: 追加写入文件
2>: 错误输出写入文件
&>: 正确和错误输出统一写入到文件中
输入重定向符号:
<: 覆盖写入文件
<<: 追加写入文件
判断命令
shell中提供了test、[、[[ 三种判断符号,可用于:
整数测试
字符串测试
文件测试
语法:
- test condition
- [ condition ]
- [[ condition ]]
注意:
- 中括号前后要有空格符
- [ 和 test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
- 中括号内的变量,最好都是使用引号括起来
- [[ 更丰富,在整型比较中支持<、>、=,在字符串比较中支持=~正则
分支语句
循环
函数
语法一:
funcName(){ echo "abc"; }
语法二:
function funcName(){ echo "abc"; }
注意:
- shell自上而下执行,函数必须在使用前定义
- 函数在获取变量和shell script类似,1、$2...获取
- 函数内return仅仅表示函数执行状态,不代表函数执行结果
- 返回结果一般使用echo、printf,在外面使用$()、``获取结果
- 如果没有return,函数状态是上一条命令的执行状态,存储在$?中
模块化
模块化的原理是在当前shell内执行函数文件,方式:
source [函数库的路径]
执行过程与原理
执行
- shell脚本一般以.sh结尾,也可以没有,这是一个约定;第一行需要指定用什么命令解释器来执行
#! /bin/bash
#! /usr/bin/env bash
- 启动方式
# 文件名运行
./filename.sh
# 解释器运行
bash ./filename.sh
# source 运行
source ./filename.sh
执行过程
- 字符解析
- 识别换行符、分号做行的分割
- 识别命令连接符(|| && 管道)做命令的分割
- 识别空格、tab符,做命令和参数的分割
- shell展开,例如{1..3}解析为 1 2 3
- 重定向,将stdin,stdout,stderr的文件描述符进行指向变更
- 执行命令
- builtin直接执行
- 非builtin使用$PATH进行查找,然后启动子进程执行
- 收集状态并返回
shell展开
大括号展开
一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分割的字符串序列,也可以是序列表达式{x..y[..incr]}
波浪号展开
shell展开
调试和前端集成
- 普通log,使用echo、printf
- 使用set命令
- vscode debug插件
vscode配置
- shellman:代码提示和自动补全
- shellcheck:代码语法校验
- shell-format:代码格式化
- Bash Debug:支持单步调试
- 安装vscode插件
- 编写launch.json文件
- 升级bash到4.以上版本
前端集成
- node中通过exec、spawn调用shell命令
- shell脚本中调用node命令
- 借助zx等库进行javascript、shell script的融合
- 借助shell完成系统操作,文件io,内存,磁盘系统状态查询等
- 借助nodejs完成应用层能力,网络io,计算等