shell

166 阅读4分钟

shell

学习shell的价值

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

01Shell基础概念

概念

终端:获取用户输入、展示运算结果的硬件设备
tty:teletypeWriter的简称,和终端等价,早期指电传打印机,在Linux中是输入/输出环境
终端模拟器:Mac Terminal、iTerm2等,关联虚拟tty的输入输出软件
Shell:command interpreter,处理来自终端模拟器的输入,解释执行之后输出结果给终端
Bash:shell的一种具体实现
Shell和Bash的关系可以理解为类和实例的关系

发展

KenThompson(来自贝尔实验室)在1971年为Unix开发了第一个shell,称为V6 shell
Stephen Bourne 在贝尔实验室为V7 Unix所开发的Bourne shell,即sh
开源组织GNU为了取代Bourne shell 开发的Bourne-Again shell 即Bash

构成

image.png

02语法和命令

变量 image.png

image.png 自定义变量

image.png 系统环境变量

image.png 配置文件加载

image.png 运算符和引用

image.png

管道

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

image.png “cat platform.access.log | grep ERROR”:使用cat查看platform.access.log里面的内容,并把内容作为grep命令的输入
“netstat -an | grep ESTABLISHED | wc -l”:使用netstat查看网络连接状态,传递给grep,grep筛选之后的结果传递给wc命令做统计

重定向

image.png

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

  • 整数测试
  • 字符串测试
  • 文件测试 语法:
  • text condition
  • [condition]
  • [[condition]]
    -z:判断字符串为空
    -n:判断字符串非空
    -e:判断文件是否存在
    -f:判断文件是否存在,并且是个普通文件
    注意:
    中括号前后要有空格符;
    []和test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
    中括号内的变量,最好都是用引号括起来
    [[]]更丰富,在整型比较中支持<、>、=,在字符串比较中支持=~正则

image.png注意使用双引号

分支语句(if和case)

image.png

image.png 解释:
首先判断level是否非空,非空的话判断level是否等于0,是否等于1。

循环

while循环
while condition;do 程序段; done
until循环
until condition;do 程序段;done
for循环
for var in [words...];do 程序段; done

函数

语法一:funcName(){echo "abc";}
语法二:function funcName(){echo "abc";}
注意:
shell自上而下执行,函数必须在使用前定义
函数获取变量和shell script类似,$0代表函数名,后续参数通过$1、$2...获取
函数内return仅仅表示函数执行状态,不代表函数执行结果 返回结果一般使用echo\printf。在外面使用$()、''获取结果
如果没有return,函数状态是上一条命令的执行状态,存储在$?中

一般在函数内定义变量,一般使用local限定一下,代表在当前作用域里生效,避免污染外部的全局作用域,如果不使用local,则后面需要使用unset来撤销一下变量。

模块化

模块化的原理是在当前shell内执行函数文件,方式: source[函数库的路径]
常用命令

image.png

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

image.png !+解释器的路径 2. 启动方式

  • 文件名运行 ./filename.sh
  • 解释器运行 bash ./filename.sh
  • source运行 source ./filename.sh
    前两个是会在子进程中执行脚本,最后一个是会在当前进程中执行脚本
    执行过程
  1. 字符解析 识别换行符、分号(;)做行的分割 识别命令连接符(||&&管道)做命令的分割 识别空格、tab符,做命令和参数的分割
  2. shell展开,例如{1..3}解析为1 2 3
  3. 重定向,将stdin、stdout、stderr的文件描述符进行指向变更
  4. 执行命令
  • builtin直接执行
  • 非builtin使用$PATH查找,然后启动子进程执行
  1. 收集状态并返回
shell展开
  1. 大括号展开(Brace Expansion){...} 一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分隔的字符串序列,也可以是序列表达式{x..y[..incr]} image.png
  2. 波浪号展开(Tilde Expansion)~ 波浪号后可以直接指定一个用户 image.png
  3. 参数展开(Shell Parameter Expansion)${} 间接参数扩展${!parameter},其中引用的参数并不是parameter而是parameter的实际值

image.png 参数长度${#parameter}

image.png(展开cd的长度)
空参数处理
${parameter:-word}# 为空替换
${parameter:=word}#为空替换,并将值赋给$parameter变量
${parameter:?word}#为空报错
${parameter:+word}#不为空替换

image.png 4.参数切片
${parameter:offset}
${parameter:offset:length}
5.参数部分删除
${parameter%word}#最小限度从后面截取word
${parameter%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命令

image.png 3.vscode debug插件

image.png

前端集成

  1. node中通过exec、spawn调用shell命令
    exec和spawn的区别:
    exec会启动一个子项去执行传入的命令,并且将命令执行的结果存在缓冲区,执行完毕之后将缓冲区的结果返回到函数当中来,缓冲区是有大小限制的,默认是200KB,如果超过限制就会报错;spawn不会启动一个子项进程,会返回一个流对象,直接对这个流对象进行写入和读取的操作,没有大小限制,比较适合大数据量的操作
  2. shell脚本中调用node命令

image.png(在脚本中用node命令去取一个js的脚本)
3. 借助zx等库进行JavaScript、shellscript的融合(shell调用:$'command')
-借助shell完成系统操作,文件io、内存、磁盘系统状态查询等
-借助node.js完成应用层能力,网络io、计算等

标题:Shell 脚本和编程 - 掘金

网址:juejin.cn/course/byte…