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

23 阅读2分钟

Shell 脚本和编程

1.学习shell的价值(有什么用?)

  1. 用来掌握Linux 服务器的基本操作和管理
  2. 也是前端 Node.js 服务的进程管理、问题排查、资源监控等运维操作
  3. 使用 shell 编写 TCE、SCM、Docker 脚本,完成服务编译和部署

2.shell的基本概念

概念

学习shell,我们首先要掌握以下概念

  1. 终端
    • 获取用户输入、展示运算结果的硬件设备
  2. tty
    • teletypeWriter的简称, 和终端等价,早期指电传打印机, 在linux 中是 输入/输出 环境
  3. 终端模拟器
    • Mac Terminal、 iTerm2等, 关联虚拟 tty 的输入输出软件
  4. Shell
    • command interpreter, 处理来自终端模 拟器的输入, 解释执行之后输出结果给终端
  5. 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及其子shellexport、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中运行

执行过程

  1. 字符解析 • 识别换行符、 分号(;) 做行的分割 • 识别命令连接符(|| && 管道) 做命令的分割 • 识别空格、tab符,做命令和参数的分割
  2. shell 展开, 例如 {1..3} 解析为 1 2 3
  3. 重定向, 将stdin、stdout、stderr的文件描述符进行指向变更
  4. 执行命令 • builtin 直接执行 • 非 builtin 使用 $PATH 查找,然后启动子进程执行
  5. 收集状态并返回 shell展开也是很重要的一点,可以多搜集资料了解

前端集成

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