[邂逅shell脚本与编程 | 青训营笔记]

117 阅读3分钟

学习shell的价值:

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

课程准备

  • 一台安装了 Linux 系统的物理机或者云主机,可运行 shell 脚本
  • 本地的 vscode 安装 Bash Debag 插件,并升级 bash 到4.x以上
  • Npm 全局安装 zx 依赖

1.Shell基础概念

2.命令和语法

3.执行过程和原理

4.调试和前端集成

-------------------------------------------------分割线-----------------------------------------------------

1.Shell基础概念

概念

image.png

tips: ShellBash能够理解为类和实例的关系

构成

Unix shell既是命令解释器,也是程序设计语言。作为一个命令解释器,Shell提供了丰富的GNU实用程序集的用户界面

image.png

语法和命令

类型作用域声明方式规范
自定义变量当前shell

=

字符串、整形、浮点型、日期型
环境变量当前shell及子shellexport、declare -x
系统环境变量所有shell启动加载

自定义变量

#!/bin/bash
# 变量名=变量值(等号左右不能有空格,有的话shell会当作额外的命令)
page_size=1
page_num=2

#命令复制给变量
_ls=ls

# 将命令结果复制给变量
file_list=$(ls - a)

# 默认字符串 ,不会进行 + 运算
total=page_size+page_num

#声明变量为整型
let total=page_size*page_num

declare -i total=page_size*page_num

#导出环境变量
export total

declare -x total

declare选项的含义

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

系统环境变量

变量名含义常见操作
$0当前shell名称/脚本名称1,1,2等可以获取到传入参数
$#传入脚本的参数数量if[ $# -gt 1 ]
$*传入脚本的所有参数
$?上条命令执行的状态码if [ $? -eq 0 ];
$PS1命令提示符export PS1="\u@\h \w>"
$HOME用户主文件夹(主目录)cd ~
$PATH全局命令的搜索路径PATH=$PATH:[新增路径]

命令和语法

配置加载文件

shell种类

  • 1.login shell 首次登陆时需要输入用户名、用户密码;
  • 2.non-login shell 细分 交互式非交互式

image.png

运算符和引用

image.png

管道

管道与管道符 | ,作用是将前一个命令的结果传递给后面的命令 语法:cmd1 | cmd2

语法:cmd1 | cmd2

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

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

#!/bin/bash

cat platform.access.log | grep ERROR

netstat -an | grep ESTABLISHED | wc -l//netstart 查看网络连接状态传递给 grep 筛选结果传递给 wc 来统计
# xargs 会将标准输入转化为参数列表
find . -maxdepth 1 -name "*.sh" | xargs ls -l

重定向

image.png

#输出重定向符号
>:覆盖写入文件
>>:追加写入文件
2>:错误输出写入文件
&>:正确和错误输出统一写入到文件中
#输入重定向符号
<
<<

判断命令

shell中提供了test、[、[[三种判断符号,可用于:

  • 整数测试
  • 字符串测试
  • 文件测试

语法:

  • test condition
  • [ condition ]
  • [[ condition ]]
#!/bin/bash

# 整数测试
test $nl -eq $n2   # 测试 $nl 是否等于 $n2
test $nl -lt $n2   # 测试 $nl 是否小于 $n2
test $nl -gt $n2   # 测试 $nl 是否大于 $n2

# 字符串测试
test -z $str_a     # 测试 $str_a 是否为空
test -n $str_a     # 测试 $str_a 是否非空
test $str_a = $str_b   # 测试 $str_a 是否等于 $str_b

# 文件测试
test -e /dmt && echo "exist"   # 测试 /dmt 是否存在,并在存在时输出 "exist"
test -f /usr/bin/npm && echo "file exist"   # 测试 /usr/bin/npm 是否存在,并在存在时输出 "file exist"

注意:

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

分支语句

在shell中分支语句有if语句和case语句

#if语句
#语法1:
if condition;then
   程序段
elif condition;then
     程序段
else
    程序段
fi #结束标志
#语法2:
case $变量 in"第一个变量内容")
      程序段
      ;;
    "第一个变量内容")
      程序段
      ;;
     *)
     程序段
     ;;
  esac

循环

#while 循环
while condition ;do 程序段; done

#until 循环
until condition ;do 程序段; done

#for 循环
for var in [word...]; do 程序段; done

函数

#语法1:
funcName(){echo"abc";}

#语法2:
function funcName(){echo"abc";} 
#内部用$获取参数

模块化

模块化的原理是在当前shell内执行函数文件,方式:

source [函数库的路径]

image.png

3.执行过程和原理

执行

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

#! /bin/bash
#! /user/bin/env bash

启动方式

#文件名运行(子进程执行)
./filename.sh

#解释器运行(子进程执行)
bash ./filename.sh

# source运行(当前进程中执行)
source ./filename.sh

image.png

绿色部分为脚本

内部运行有几个部分:

1.字符解析

  • 识别换行符、分号(;)做行的分割

  • 识别命令连接符(||&&管道)做命令的分割

  • 识别空格、tab符,做命令和参数的分割

2.shell展开,例如{1...3}解析为1 2 3

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

4.执行命令

  • builtin直接执行

  • 非builtin使用$PATH查找,然后启动子进程执行

5.收集状态并返回给脚本

shell展开

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

  • 波浪号展开(Tilde Expansion) ~

  • 参数展开(Shell Parameter Expansion)

  • 命令替换(Command Substitution)

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

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

4.调试和前端集成

调试的方法

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

Vscode插件配置

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

  2. shellcheck:代码语法校验

  3. shell-format:代码格式化

  4. Bash Debug:支持单步调试

  • 安装vscode插件

  • 编写launch.json文件

  • 升级bash到4.x以上版本

前端集成

1.node中通过exec、spawn调用shell命令

2.shell脚本中调用node命令

3.借助zx等库进行javascript、shell script的融合

  • 借助shell完成系统操作,文件io、内存、磁盘系统状态查看
  • 借助nodejs完成应用层能力,网络io、计算等 image.png

image.png

完成对shell的学习,好记心不如烂笔头,不做笔记不实践是永远没有进步的。