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

120 阅读4分钟

Shell是一种命令行界面,也是一种编程语言, 熟练掌握 Shell 能够大大提升 Unix/Linux环境下的工作效率。

Shell的语法和命令

Shell的自定义变量的作用域是当前Shell,声明方式是=,规范是字符串、整型、浮点型和日期型。环境变量的作用域是当前shell及其子shell,声明方式是export、declare-x。系统环境变量的作用域是所有shell,声明方式是启动加载。

shell的自定义变量书写格式

image.png

declare[+/-] 选项 变量

image.png

系统环境变量

image.png

运算符的符号、作用和用法

image.png

管道

管道与管道符|的作用是将前一个命令的结果传递给后面的命令。

语法:

cmd1 | cmd2

要求:

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

注意:

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

image.png

重定向

重定向可以用来修改默认的引用关系

image.png

判断命令

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

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

  • 以test为例:

image.png

语法:

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

注意:

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

分支语句

语法1:

if condition;then

程序段

elif condition;then

程序段

else

程序段

fi

注:"condition"是判断条件;有多个分支时可使用"elif"(其实就是elseif);"fi"是结尾

示例:

image.png

语法2:

case $变量 in:

"第一个变量内容")

程序段

;;

"第一个变量内容")

程序段

;;

*)

程序段

;; easc

注:";;"代表分割;最后的默认分支需要用"*)";"easc"是结尾

示例:

image.png

循环

  • while循环

while condition;do程序段;done

  • until循环

until condition;do程序段;done

  • for循环

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

注: until循环与while循环完全相反,表示条件成立时跳出循环;for循环有两种写法:对列表进行循环、数值方式循环

函数

  • 语法一:

funcName(){echo"abc";}

  • 语法二:

function funcName(){echo"abc";}

注意:

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

模块化

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

source[函数库的路径]

示例:

image.png

常用命令

image.png

Shell执行过程和原理

执行

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

image.png 2、启动方式

image.png 注: 文件名运行的前提是此文件名有可执行权限;文件名运行和解释器运行会在子进程中执行脚本,source运行会在当前进程中执行脚本

执行过程

1. 字符解析

  • 识别换行符、分号(;)做行的分割
  • 识别命令连接符(|| && 管道)做命令的分割
  • 识别空格、tab符,做命令和参数的分割

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

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

4.执行命令

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

5.收集状态并返回

image.png

Shell展开

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

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

image.png

2. 波浪号展开(Tilde Expansion) ~

image.png

3. 参数展开(Shell Parameter Expansion) ${}

1.间接参数扩展${!parameter},其中引用的参数并不是parameter而是parameter的实际的值

2.参数长度${#parameter}

3.空参数处理

  • ${parameter:-word}#为空替换
  • {parameter:=word}#为空替换,并将值赋给parameter变量
  • ${parameter:?word}#为空报错
  • ${parameter:+word}#不为空替换

4.参数切片

  • ${parameter:offset}
  • ${parameter:offset:length}

5.参数部分删除

  • ${parameter%word}#最小限度从后面截取word
  • ${parameter6%word}#最大限度从后面截取word
  • ${parameter#word}#最小限度从前面截取word
  • ${parameter##word}#最大限度从前面截取word

image.png

4. 命令替换(Command Substitution)

在子进程中执行命令 并用得到的结果替换包裹的内容, 形式上有两种:$(...)或 '...'(实际上'应该是`的,但是打不出来)

image.png

5. 数学计算(Arithmetic Expansion) $((..))

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

image.png

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

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

image.png

调试

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

注: 一般在shell最开头使用set进行以下配置

image.png

vscode配置

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

注: 使用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