Shell脚本和编程

148 阅读2分钟

学习shell的价值

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

课程总览

  1. Shell基础概念
  2. 命令和语法
  3. 执行过程和原理
  4. 调试和前端集成

Shell基础

  • 概念

在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。它类似于DOS下的COMMAND.COM和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。

  • 构成

Unix shell既是一个命令解释器也是一种编程语言。作为命令解释器,shell为丰富的GNO工具集提供了用户接口

下载.png

语法和命令

变量

QQ图片20230417214645.png

父子shell

自定义变量

#变量名=变量值(等号左右不能有空格) page_size=1 page_num=2

#将命令复制给变量 _ls=ls

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

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

declare -i total=page_size*page_num

#导出环境变量 export total

declare -x total

56300f4c-ad45-4c8d-92c1-4b065d82a27a.png

系统环境变量

QQ图片20230417220146.png 注意:Bash Shell在启动时总要配置其运行环境,例如初始化环境变量、设置命令提示符、指定系统命令路径等

配置文件加载

下载 (1).png 注意:登录式进入主机需要输入用户名和密码;非登录式分为交互式和非交互式

运算符和引用

QQ图片20230417220630.png

管道

管道与管道符|,作用1将前一个命令的结果传递给后面的命令 语法:cmd1|cmd2 要求:管道右侧的命令必须能接受标准输入才行,比如grep命令,ls、mv等不能直接使用,可以使用xargs预处理 注意:管道命令仅仅处理stdout,对于stderr(错误)会予以忽略,可以使用set -o pipefail设置shell遇到管道错误退出

重定向

  • 输出重定向符号

(>:覆盖写入文件) (>>:追加写入文件) 2>:错误输出写入文件 &>:正确和错误输出统一写到文件中

  • 输入重定向符号

< <<

判断命令

  • shell中提供了test、[、[[三种判断符号,可用于:
  1. 整数测试
  2. 字符串测试
  3. 文件测试
  • 语法:
  1. test condition
  2. [ condition ]
  3. [[ condition ]]

注意:

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

分支语句

语法1: if condition; then 程序段 elif condition; then 程序段 else 程序段 fi

语法2: case $变量 in: "第一个变量内容") 程序段 ;; "第一个变量内容") 程序段 ;; *) 程序段 ;; esac

循环

  • while循环

while condition ; do 程序段; done

  • until循环

until contidion ; do 程序段; done

  • for循环

for var in [words...]; do 程序段; done

函数

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

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

注意:

  • shell自上而下执行,函数必须在使用前定义
  • 函数获取变量和shell script类似,0代表函数名,后续参数通过0代表函数名,后续参数通过1、$2...获取
  • 函数内return仅仅代表函数执行状态,不代表函数执行结果
  • 返回结果一般使用echo、printf,在外面使用 $()、``获取结果
  • 如果没有return,函数状态是上一条命令的执行状态,储存在$?中

模块化

模块化的原理就是在当前 shell内执行函数文件,方法: source[函数库路径]

常用命令

QQ图片20230417223219.png

执行过程和原理

执行

  1. shell脚本一般以.sh结尾,也可以没有,这是一个约定:第一行需要指定用什么命令解释器来执行
  2. #文件名执行 ./filename .sh #解释器运行 #source执行

执行过程

  1. 字符解析
  • 识别换行符、分号(;)做行的分割
  • 识别命令连接符(|| && 管道)做命令的分割
  • 识别空格、tab符,做命令和参数的分割
  1. shell展开,将stdin、stdout、stderr的文件描述符进行指向变更
  2. 重定向,将stdin、stdout、stderr的文件描述符进行指向变更
  3. 执行命令

shell展开

大括号展开(){...}

一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分割的字符串序列,也可以是序列表达式{x..y[..incr]}

波浪号展开 ~

参数展开 ${}

  1. 间接参数扩展${! parameter},其中引用的参数并不是parameter而是parameter的实际的值
  2. 参数长度 ${#parameter}
  3. 空参数处理
  4. 参数切片
  5. 参数部分删除

命令替换

在子进程中执行命令,并用得到的结果替换包裹的内容,形式上有两种:$(...)或`...`

数学计算

使用$(()) 包裹数学运算表达式,得到结果并替换

文件名展开

当有单词没有被引号包裹,且其中出现了'*' '?' and '['字符,则shell会去按照正则匹配的方式查找文件名进行替换,如果没有找到则保持不变

调试和前端集成

调试

  1. 普通log,使用echo、print
  2. 使用set命令
  3. vscode debug插件

QQ图片20230417224943.png

VScode配置

  1. shellman :代码提示和自动补全
  2. shellcheck: 代码语法校验
  3. shell-format:代码格式化
  4. Bash Debug :支持单步调试

前端集成

  1. node中通过exec、spawn调用shell命令
  2. shell脚本中调用node命令
  3. 借助zx等库完成javascript、shell script的融合

255ffa27-9a99-4257-b488-cbb6c9988eca.png