Shell 脚本和编程
1.学习shell的价值(有什么用?)
- 用来掌握Linux 服务器的基本操作和管理
- 也是前端 Node.js 服务的进程管理、问题排查、资源监控等运维操作
- 使用 shell 编写 TCE、SCM、Docker 脚本,完成服务编译和部署
2.shell的基本概念
概念
学习shell,我们首先要掌握以下概念
- 终端
- 获取用户输入、展示运算结果的硬件设备
- tty
- teletypeWriter的简称, 和终端等价,早期指电传打印机, 在linux 中是 输入/输出 环境
- 终端模拟器
- Mac Terminal、 iTerm2等, 关联虚拟 tty 的输入输出软件
- Shell
- command interpreter, 处理来自终端模 拟器的输入, 解释执行之后输出结果给终端
- Bash
- 是shell的一种具体实现
发展
Ken Thompson(来自贝尔实验室)在 1971 年为 UNIX开发了第一个 shell,称为 V6 shell;Stephen Bourne 在贝尔实验室 为 V7 UNIX 所开发的 Bourneshell , 即 sh;开源组织 GNU 为了取代 Bourne shell 开发的Bourne- Again shell, 即 Bash。
构成
- shell
- 解释器
- bash内置命令
- GNU核心工具集
- 第三方库
- 编程语言
- 变量
- 自定义变量
- 环境变量
- 系统环境变量
- 运算
- 逻辑运算符
- 算术运算符
- 语句
- 判断
- 分支
- 循环
- 函数
- 变量
- 解释器
3.语法和命令
变量
类型 | 作用域 | 声明方式 | 规范 |
---|---|---|---|
自定义变量 | 当前shell | = | 默认字符串,也可以是整型,浮点型,日期型 |
环境变量 | 当前shell及其子shell | export、declare -x | |
系统环境变量 | 所有shell | 启动加载 |
父子shell
当前shell(父进程)执行一个被父进程触发的shell(子进程)时,自身处于暂停状态,等执行完后,从子进程exit,父进程继续执行下一条命令
自定义变量
delcare + - -a -i -x -r -p都有不同含义,要牢记
系统环境变量
变量名 含义 常见操作
$0 当前 shell 名称/脚本名称 $1、$2等可以获取到传入参数
$# 传入脚本的参数数量 if [ $# -gt 1 ]
$* 传入脚本的所有参数
$? 上条命令执行的状态码 if [ $? -eq 0 ];
$PS1 命令提示符 export PS1="\u@\h \w> " $HOME 用户主文件夹 cd ~
$PATH 全局命令的搜索路径 PATH=$PATH:[新增路径]
配置文件加载
login shell 和non-login shell两种方式
运算符和引用
类型 符号 作用 用法
算数运算符 + - * / % | & 常规运算
逻辑运算符 || && !
比较运算符 == != < >
引号
双引号 "" 部分引用, 仅仅 $ ` \ 保留作用 foo="${a}123" 单引号 '' 完全引用,原样输出 foo=‘foo$a’
反引号 `` 执行命令 foo=`ls -a` 圆括号
(()) 算数运算 foo=$((1+2))
() 执行命令 $(ls -a)
命令连接
|| cmd1 执行完且返回码非0 ,则继续执行
cmd2
cmd1 || cmd2
&&
cmd1 执行完且返回码为0 ,则继续执行
cmd2
cmd1 && cmd2
; cmd1、cmd2 串行执行 cmd1 ; cmd2
后台运行 & 让命令在后台运行,可与nohup一起使
用
cmd &
管道
管道与管道符 | ,作用是将前一个命令的结果传递给后面的命令 语法: cmd1 | cmd2 要求: 管道右侧的命令必须能接受标准输入才行, 比如 grep 命令, ls、mv等不能直接使用,可以使用 xargs 预处理 注意: 管道命令仅仅处理 stdout, 对于 stderr 会予以忽略, 可以使用 set -o pipefail 设置 shell 遇到管道错误
判断符号
test、[、[[三种判断符号
分支语句 循环 函数 模块化
执行过程和原理
shell脚本一般以.sh为结尾,没有也行 三种启动方式
#文件名运行
./filename.sh
#解释器运行
bash ./filename.sh
#source运行
source ./filename.sh
前两种会开一个子shell在其中运行,第三种会在当前shell中运行
执行过程
- 字符解析 • 识别换行符、 分号(;) 做行的分割 • 识别命令连接符(|| && 管道) 做命令的分割 • 识别空格、tab符,做命令和参数的分割
- shell 展开, 例如 {1..3} 解析为 1 2 3
- 重定向, 将stdin、stdout、stderr的文件描述符进行指向变更
- 执行命令 • builtin 直接执行 • 非 builtin 使用 $PATH 查找,然后启动子进程执行
- 收集状态并返回 shell展开也是很重要的一点,可以多搜集资料了解
前端集成
- node中通过 exec、spawn 调用 shell 命令
- shell 脚本中调用 node 命令
- 借助 zx 等库进行 javascript、 shell script 的融合
- 借助 shell 完成系统操作, 文件io、内存、磁盘系统状态查询等
- 借助 nodejs 完成应用层能力, 网络io、计算等