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

118 阅读5分钟

本文参与青训营笔记创作活动

学习shell的价值

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

shell基础概念

什么是shell?

  1. shell是操作系统的最外层,是一个用户跟操作系统之间交互的命令解释器
  2. 大多数linux默认的shell命令解释器是 bash(/bin/bash)
  3. shell独立于内核,是链接内核和应用程序的桥梁,通俗来讲shell是内核周围的外壳

概念

image.png 物理终端 => 软件终端tty => 终端模拟器 => shell

  • tty 或者说终端最开始指的是获取用户输入并输出的物理设备, 比如电传打字机。在 linux 中是接收用户输入、输出结果的终端仿真软件, 比如我们用的 mac terminal、 iterm2 等, 更强输入辅助功能、画面绘制输出的模拟终端器;
  • 而 tty 变成一个虚拟概念, 是linux的一个程序,每个终端模拟器关联一个虚拟 tty ,和内核打交道。 我们可以在 终端模拟器中输入 tty 查看关联到的虚拟 tty
  • bash是 shell的一种具体实现, 可以理解成 实例和类的关系

发展

image.png

  • 除了替代 v6 shell,sh 还有几个优点,把控制流程,循环,变量引入了脚本,提供了一种更具功能性的语言
  • 主流 Linux 系统使用的 shell,许多都以它为锚点。
  • bash是 sh 的超集,可以直接执行大部分 sh 脚本。 Bash 在兼容 Bourne shell 脚本编程的同时,集成了 Korn shell 和 C shell 的功能,包括命令历史,命令行编辑,目录堆栈(pushd 和 popd),一些实用环境变量,命令自动补全等。

构成

image.png

  • shell 不仅提供了与内核和设备交互的方法,还集成了一些今天软件开发中通用的设计模式(比如管道和过滤器), 具备控制流程,循环,变量, 命令查找的机制
  • 既是命令解释器, 也是一门编程语言, 作为命令解释器, 它提供给用户接口,使用丰富的 GNU 工具集, 第三方的或者内置的, 比如 cd、pwd、exec、test、 netstat 等等

shell语法和命令

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

父子shell:

image.png

自定义变量

image.png

  • declare的后缀参数: image.png

系统环境变量

变量名含义常见操作
$0当前shell名称/脚本名称$1$2等可以获取到传入参数
$#传入脚本的参数数量if[$# -gt1]
$*传入脚本的所有参数
$?上条命令执行的状态码if[$?-eq0]
$PS1命令提示符export PS1="\u@\h \w >"
$HOME用户主文件夹cd~
$PATH全局命令的搜索路径PATH=$PATH:[新增路径]
  • 修改默认配置(例如PS1)时,需要通过vim进入默认的.bashrc文件,修改完成后还需要source重置 image.png
  • 配置文件加载
    image.png
    • 通过系统用户登录默认运行的shell。
    • 非登录交互式运行shell
    • 执行脚本运行非交互式shell

如果取得 bash 需要完整的登录流程, 我们称之为 login shell, 比如 ssh 远程登录一台主机。
不需要登录的bash 我们称为 non-login bash, 比如在原来的 bash 中执行 bash开启子进程、执行一些外部命令。
如果修改了配置文件,不会立即生效,需要我们重启终端或者执行 source 命令

运算符和引用

image.png

管道

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

image.png

重定向

image.png 每个 shell 命令在执行时都会打开三个文件描述符, 文件描述符0、1、2, 分别对应 stdin、stdout、stderr, 这三个文件描述符默认指向 终端输入、终端输出,那么当命令需要获取输入的时候,它会去读取 fd0, 当要输出的时候它会像 fd1、fd2写入, 改变这些描述符指向的行为叫做 重定向

输出重定向符号

  • >:覆盖写入文件
  • >>:追加写入文件
  • 2>:错误输出写入文件(2>&1 必须写在 > 之后)
  • &>:正确和错误输出统一写入到文件中

输入重定向符号<<<( << 比较特殊, 表示继续沿用当前的标准输入, 只是当识别到指定的标识符后停止, 将接收到的内容作为 stdin)

判断命令

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

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

image.png 语法

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

注意:

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

分支语句

语法1:
if condition ; the
    程序段
elif condition ; the
    程序段
esle
    程序段
fi

image.png

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

image.png

循环

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

函数

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

image.png 注意:

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

模块化

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

image.png

常用命令

image.png

待更新.....