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

101 阅读3分钟

一、Shell基础概念

概念

  • 终端:获取用户输入、展示运算结果的硬件设备
  • tty:与终端等价,早期值电传打印机,在Linux中指输入/输出环境
  • 终端模拟器:关联虚拟tty的输入输出软件
  • Shell:处理来自终端模拟器的输入,解释执行之后输出结果给终端
  • Bash:shell的一种具体实现

二、语法和命令

1.自定义变量

  • 等号两边不能有空格,否则shell会当作额外命令
  • 可以将命令直接赋值给变量,如:_ls=ls
  • 可以将命令执行结果赋值给变量,如:_result=$(ls -a)
  • 声明变量为整型时,需要在变量名前加上 let/declare -i ,否则,编译器会默认该变量类型为字符串类型,如:
a=1
b=2
num=a*b //num默认为字符串,无法进行运算
let num=a*b
declare -i num=a*b
  • 导出环境变量用 export/declare -x ,如:
export num
declare -x num

2.declare的部分操作

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

3.系统环境变量

image.png

4.配置文件加载

shell文件分为两种:

  1. 登录式:首次登录主机时输入用户名和密码
  2. 非登录式:
  • 登录后打开的终端shell
  • 非登录式又分为交互式和非交互式
  1. 修改了某个配置文件后,要用 source ~/.bashrc 去执行一下文本,才能生效

5.运算符

  • 双引号 "" :部分引用,仅仅 $ ` \ 保留作用
  • 单引号 '' :完全引用,引号中内容原样输出
  • 反引号 `` :执行反引号中命令并输出
  • 后台运行& :让命令在后台运行,可与nohup一起使用 与nohup一起使用可以保证shell关闭后,后台运行的服务不会被一起关闭,保持运行状态

6.管道

  • 语法:cmd1 | cmd2

    前一个命令的结果传递给后面的命令

  • 要求:管道右侧的命令必须能够接受标准输入,比如grep命令,ls、mv等不能直接使用,但可以用xargs预处理

  • 注意:管道命令仅仅处理stdout,对于stderr会予以忽略,但可以使用 set -o pipefail 设置shell遇到管道错误退出

7.重定向

  1. 输出重定向符号
  • '>'/'1>': 覆盖写入对象
  • '>>': 追加写入对象
  • '2>': 错误输出写入文件
  • '&>': 正确和错误输出同一写入到文件中
  1. 输入重定向符号
  • <
  • <<

8.判断命令

可用于整数测试、字符串测试、文件测试

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

注意

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

9.函数注意点

一般在函数内部定义变量时,会使用local去限定一下,代表在当前作用域内生效,避免污染外部的全局作用域;不适用local的话,则可以使用unset将变量撤销

image.png

10.模块化

在当前shell内执行函数文件

方式:source [函数库路径]

11.常用命令

  • -a 前几行
  • -n 后几行
  • -f 读取到文件末尾后,不停止命令执行,继续等待文件输入(排查问题时)

image.png

三、执行过程和原理

1.启动方式

  • 以文件名运行:./filename.sh(要求有可执行权限,子进程中执行脚本)
  • 解释器运行:bash ./filename.sh(子进程中执行脚本)
  • source运行:source ./filename.sh(当前进程中执行脚本)

2.shell展开

  1. 大括号展开
  • 字符串序列
  • 表达式序列(连续/等差)
  1. 波浪号展开
  • 当前用户主目录 ~
  • 指定用户的主目录 ~/foo
  • 当前工作目录 ~+/foo
  • 上一个工作目录 ~-/foo
  1. 参数展开
  • 间接参数展开 $(!parameter)
  • 参数长度 $(#parameter)
  • 空参数处理

$(parameter:-word) # 为空替换

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

$(parameter:?word) # 为空报错

$(parameter:+word) # 不为空替换

  • 参数切片

$(parameter:offset)

$(parameter:offset:length)

  • 参数部分删除

$(parameter%word) # 最小限度从后面截取word

$(parameter%%word) # 最大限度从后面截取word

$(parameter#word) # 最小限度从前面截取word

$(parameter##word) # 最大限度从前面截取word 4. 命令替换 5. 数学计算 6. 文件名展开

四、调试和前端项目集成

1.调试

  1. 普通log,使用echo、printf
  2. 使用set命令
  • -u 遇到不存在的变量就会报错,并停止执行
  • -x 运行结果之前,先输出执行的那一行命令
  • -e 只要发生错误,就终止运行
  • -o pipefail 管道符连接,只要一个子命令失败,整个管道命令失败,脚本终止运行
  1. vscode debug插件

2.前端集成

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