一、课程介绍
Shell是一种命令行界面,也是一种编程语言, 熟练掌握 Shell 能够大大提升 Unix/Linux环境下的工作效率。本课程将从其发展历史、基础语法开始,通过示例逐步深入, 不仅帮助大家学会使用 Shell ,也在一定程度上去理解 Shell 的执行原理和语法设计。
二、课程重点
- shell 基础和语法
- shell 执行过程和原理
- shell 调试和前端集成
三、学习shell的价值
①Linux服务器的基本操作和管理
②前端Node.js服务的进程管理、问题排查、资源监控等运维操作
③使用shell编写TCE、SCM、Docker脚本,完成服务编译和部署
四、课程准备
- 一台安装了linux 系统的物理机或者云主机,可运行shell脚本
- 本地的vscode 安装Bash Debug 插件, 并升级bash到4.x以上
- Npm全局安装zx依赖
Shell基本概念
shell是外壳的意思,就是操作系统的外壳。我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包括ls、cd、pwd等等。总结来说,Shell是一个命令解释器,它通过接受用户输入的Shell命令来启动、暂停、停止程序的运行或对计算机进行控制。
shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。 shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序。
发展
- Ken Thompson (来自贝尔实验幸)在 1971 年为 UNIX开发了第一个 shell,称为 V6 shell
- Stephen Boure 在贝尔实验室 为 V7 UNIX 所开发的Bourne shell , 即 sh
- 开源组织 GNU 为了取代 Bourme shell 开发的Bourne-Again shell,即 Bash
构成
语法和命令
自定义变量
其中declare选项及其含义如下:
系统环境变量
- $0:表示当前执行的脚本或命令的名称
- $#:表示命令或脚本要处理的参数的个数
- $*:把所有的参数看成以空格分隔的一个字符串整体(单字符串)返回
- $?上条命令执行的状态码
- $PS1命令提示符
- $HOME用户主文件夹
- $PATH全局命令的搜索路径
运算符和引用
管道
管道与管道符|,作用是将前一个命令的结果传递给后面的命令
语法:cmd1 | cmd2
要求:管道右侧的命令必须能接受标准输入才行,比如 grep 命令,ls、mv等不能直接使用,可以使用 xargs 预处理
注意:管道命令仅仅处理 stdout,对于 stderr 会予以忽略,可以使用 set -o pipefail 设置 shell 遇到管道错误退出
重定向
重定向可以让我们的程序的标准输出、错误输出的信息重定向文件里,那么么这里还可以将文件的内容代替键盘作为一种标准输入的方式,在C语言的函数为:dup。
输入重定向符号“<” ,“<<”
输出重定向符号“>”,“>>”,“2>”,“&>”
判断命令
shell中提供了test、 [ 、[[ 三种判断符号,可用于:
- 整数测试
- 字符串测试
- 文件测试
语法
- test condition
- [condition]
- [[condition]]
注意
- 中括号前后要有空格符;
- [和test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
- 中括号内的变量,最好都是用引号括起来 -[[更丰富, 在整型比较中支持<、>、=,在字符串比较中支持=~正则
分支语句
shell中分支语句主要是两种:
-
if语句
if语句经常用在分支不是很多的场景下,if后面的指令,首先会被执行,然后根据指令的返回状态码进入对应的分支。如果状态码为0,也就 是指令执行成功,就进去then的部分;非0则进入其他分支。
语法:
- case语句
循环
三种循环:
- while循环
只要条件成立,则反复循环,不成立即停止
- until循环 重复测试某个条件,只要条件不成立则反复循环
- for循环 for循环,又有人称之为条件循环,或者for i in ,其实就是for循环的特性,次数和给与的条件是成正比的
函数
将命令序列按格式写在一起,可方便重复使用命令序列 语法
- funcName(){echo "abc"}
- function funcName(){echo "abc"}
注意:
- shell自上而下执行,函数必须在使用前定义
- 函数获取变量和 shell script类似,0代表函数名,后续参数通过0代表函数名,后续参数通过0代表函数名,后续参数通过1、$2...获取
- 函数内 return仅仅表示函数执行状态, 不代表函数执行结果
- 返回结果一般使用 echo、 printf,在外面使用$()、'' 获取结果
- 如果没有 return,函数状态是上一条命令的执行状态,存储在$?中
函数返回值
return表示退出函数并返回一个退出值,脚本中可以用 $ ? 变量显示该值
使用原则:
函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
退出状态码必须是0~255,超出时值将为除以256取余
shell展开
- 大括号展开(Brase Expansion) {..}
一般由三部分构成:前缀,大括号,后缀 大括号展开是一种可以生成任意字符串的机制。展开大括号的模式采用可选的前缀,后接一系列逗号分隔的字符串或一对大括号之间的序列表达式,后接可选的后缀。前缀与大括号中包含的每个字符串组合,然后将后缀附加到每个结果字符串,从左到右展开。
- 波浪号展开(Tilde Expansion) ~
如果一个单词以未加引号的斜杠字符(’ ~ ')开头,则第一个未加引号的斜杠之前的所有字符(如果没有加引号的斜杠,则所有字符)都被视为波浪前缀。如果波浪号前缀中的字符都没有被引用,那么波浪号后面的波浪号前缀中的字符将被视为可能的登录名。如果这个登录名是空字符串,则用shell变量HOME的值替换波浪号。如果没有设置HOME,则替换执行shell的用户的HOME目录。否则,波浪前缀将被替换为与指定登录名关联的主目录。
- 参数展开
- 间接参数扩展${!parameter}
- 参数长度${#parameter}
- 空参数处理:parameter:−word为空替换;{parameter:-word}为空替换;parameter:−word为空替换;{parameter:=word}为空替换,并赋值给parameter变量;parameter变量;parameter变量;{parameter:?word}为空报错;${parameter:+word}不为空替换。
- 参数切片
- 参数部分删除
- 命令替换
命令替换允许命令的输出替换命令本身。
- $(...)
- ...
- 数学计算(Arithmetic Expansion) $((..))
使用$(())包裹数学运算表达式,得到结果并替换。
- 文件名展开(Filename Expansion) ?[..]外壳文件名模式匹配 当单词没有被引号包裹,且出现' ' '?' '['字符,shell会按照正确的方式查找文件名替换,如果没找到保持不变。
VSCode配置
- shellman:代码提示和自动补全
- shellcheck:代码语法校验
- shell-format:代码格式化
- Bash Debug:支持单步调试
前端集成
- node中通过exex ,spawn 调用shell命令
- shell脚本中调用node命令
- 借助zx等库进行javascript,shell script的融合
文本处理工具
①cut cut 的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
语法:
cut [选项参数] filename
选项参数
awk
awk是一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
语法: awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}…’ filename pattern:表示 awk 在数据中查找的内容,就是匹配模式 action:在找到匹配内容时所执行的一系列命令