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

146 阅读4分钟

Shell 脚本和编程

前言

shell作用:

1、Linux服务器的基本操作和管理

2、前端Node.js服务的进程管理、问题排查、资源监控等运维操作

3、使用shell编写TCE、SCM、Docker脚本,完成服务编译和部署

环境准备:

1、linux物理机或云主机

2、vscode安装Bash Debug插件,bash版本4.x

3、Npm全局安装zx依赖

npm - -g zx

大纲

1、shell基础概念

2、命令和语法

3、执行过程和原理

4、调试和前端集成

一、shell基础概念

1、shell作为命令语言,同时它又是一种程序设计语言。它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。 image.png 具体可参考百度百科

二、命令和语法

1、变量

变量分为三种类型自定义变量环境变量系统环境变量,不同类型的变量其作用域不同,依次:当前shell当前shell和子shell所有shell 具体可参考下图: image.png

1、自定义变量

下面是一些自定义变量的声明

#!/bin/bash
# 变量名=变量值(等号左右不有空格)
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

2、系统环境变量

详细参考下图:

image.png

注意:PS1PS1、HOME、$USER这些都是区分大小写的,小写是不会正常拿到结果的。

image.png

2、配置文件加载

1、登录式shell,在加载时从/etc/profile文件开始--再去加载--》bash_profile、bash_login、profile----》bashrc----》/etc/bashrc。

2、非登录式shell,在加载时直接加载bashrc---->/etc/bashrc

source 文件重新加载资源

3、运算符和引号

详细参考下图: image.png 这些符号会常用到,不必硬背,多练多熟悉即可。

4、管道

管道与管道符|,它的作用是将前一个命令的结果传递给后面一个命令。在前面Linux的学习中我没知到,进程和进程之间也可也通过管道联系起来,管道起到桥梁作用吧。

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

注意: 管道命令仅仅处理标准输出,对于标准错误输出会被忽略。可以使用set -o pipefail来设置shell遇到管道错误退出。

#!/bin/bash

cat platform.access.log | grep ERROR # 查看日志输入

netstat -an | grep ESTABLISHED | wc -l # 查看网络连接状态

find . -maxdepth 1 -name "*.sh" | xargs ls -l # 查看文件名,显示文件信息(xargs 对find的结果做预处理,使得ls可以连接管道)

5、重定向

1、输出重定向符号:

覆盖写入文件 >

追加写入文件 >>

错误输出写入文件 2>

正确和错误输出统一写入到文件中 &>

2、输入重定向符号:

<、<<

6、判断命令

shell中提供 test、[、[[三种判断符号,可用于:
  • 整数测试
  • 字符串测试
  • 文件测试
  • 语法
    • test condition
    • 【 condition 】
    • 【【 condition 】】

注意:

1、中括号前后要有空格符;

2、【和test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串

3、中括号内的变量,最好都是用引号括起来

3、【【更丰富,在整形比较中支持<、>、=,在在字符串比较中支持正则

7、分支语句

语法一:

if condition ;then
    code
elif condition ;then
    code
else
    code
fi

语法二:

case $变量 in:
    "第一个变量内容")
        code
        ;;
    "第一个变量内容")
        code
        ;;
    *)
    code
    ;;
    esac

8、循环语句

  • while循环
    • while condition ; do code;done
  • until循环
    • ubitl condition ; do code;done
  • for循环
    • for var in [words...]; do code; done

9、函数

语法一: funcName(){ echo "adc"; }

语法二: function funcName() { echo "adc"; }

注意:

1、shell自上而下执行,函数必须在使用前定义

2、函数获取变量和 shell script类似,0代表函数名,后续参数通过0代表函数名,后续参数通过1、$2...获取

3、函数内 return 仅仅表示函数执行状态,不代表函数执行结果。

4、返回结果一般使用echo、printf,在外部使用$()、 获取结果

5、如果没有 return ,函数状态是上一条命令的执行状态,存储在$?中。

10、模块化

通过source来引入函数,实现shell模块化操作

source './math.sh'引入函数

11、常用命令

常用shell命令参考下图: image.png

三、执行过程和原理

1、shell脚本的格式:

shell脚本文件一般以.sh结尾,也可以没有;
第一行需要指定用说明命令解释器来执行,如下:
#!/bin/bash  或者  #!/usr/bin/env bash

2、shell文件的启动方式:

文件名运行:./文件名  (在子进程中执行)

解释器运行:bash ./文件名    (在子进程中执行)

source运行: source ./文件名    (在当前进程中执行)

shell的执行过程

  1. 字符解析
    • 识别换行符、分号(;)做行的分割
    • 识别命令连接符(| & ||)
    • 识别空格、tab做命令和参数分割
  2. shell展开
    • 大括号展开
    • 波浪号展开
    • 参数展开
    • 命令替换
    • 数学计算
    • 文件名展开
  3. 重定向,将标准输入、输出,错误输出的文件描述符进行指向变更
  4. 执行命令
    • builtin 直接执行
    • 非builtin 使用$PATH 查找,然后启动子进程执行.
  5. 收集状态并返回

四、调试和前端集成

1、调试

普通log,使用echoprintf
使用set命令
vscode debug插件

2、前端集成

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

2、shell脚本中调用node命令

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

总结:

image.png