day3 Shell脚本和编程
Shell基础
概念
- 终端:获取用户输入、展示运算结果的硬件设备
- tty:teletypeWriter,与终端等价,在linux中是输入/输出
- 终端模拟器:Mac Terminal、iTerm2等,关联虚拟tty的输入输出软件
- Shell:处理来自终端模拟器的输入,解释执行之后输出结果给终端
- Bash:shell的一种具体实现(可以理解为类与实例)
物理终端=>软件终端tty=>终端模拟器=>Shell
发展
graph LR
1971年\n\nv6shell --> BourneShell\n\nsh --> Bourne-AgainShell\n\nBash
构成
- 解释器
- bash内置命令
- GNU核心工具库
- 第三方库
- 编程语言
- 变量
- 运算
- 语句
- 函数
Shell语法和命令
变量
| 类型 | 作用域 | 声明方式 | 规范 |
|---|---|---|---|
| 自定义变量 | 当前shell | = | 字符串、整型、浮点型、日期型 |
| 环境变量 | 当前shell及其子shell | exprot、 declare -x | |
| 系统环境变量 | 所有shell | 启动加载 |
declare选项的含义
| 选项 | 含义 |
|---|---|
| - | 给变量设定类型属性 |
| + | 取消变量的类型属性 |
| -a | 将变量声明为数组类型 |
| -i | 将变量声明为整数型 |
| -x | 将变量声明为环境变量 |
| -r | 将变量声明为只读变量 |
| -p | 显示指定变量的被声明的类型 |
系统环境变量
| 变量名 | 含义 | 常见操作 |
|---|---|---|
| $0 | 当前shell名称/脚本名称 | 2等可以获取到传入参数 |
| $# | 传入脚本的参数数量 | if[$# -gt 1] |
| $* | 传入脚本的所有参数 | |
| $? | 上条命令执行的状态码 | if[$? -q 0]; |
| $PS1 | 命令提示符 | export PS1="\u@\h\w>" |
| $HOME | 用户主文件夹 | cd ~ |
| $PATH | 全局命令的搜索路径 | PATH=$PATH:[新增路径] |
管道
管道与管道符|,作用是将前一个命令的结果传递给后面的命令
- 语法:cmd1 | cmd2
- 要求:管道右侧命令必须能接受标准输入,比如grep命令,ls、mv等不能直接使用,可以使用xargs预处理
- 注意:管道命令仅仅处理stdout,对于stderr会予以忽略,可以使用set -o pipefail设置shell遇到管道错误退出
重定向
输出重定向
-
:覆盖写入文件
-
:追加写入文件
- 2>:错误输出写入文件
- &>:正确和错误输出统一写入到文件中
输入重定向符号
- <
- <<
判断命令
shell中提供了test、[]、[[]]三种判断符号,可用于
- 整数测试
test condition - 字符串测试
[ condition ] - 文件测试
[[ condition ]]
注意:
- 中括号前后要有空白符
- [] 和test 是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
- 中括号内的变量,最好都用引号括起来
- [[]]更丰富,在整型比较中支持<、>、=,在字符串中支持=~正则
分支语句
-
语法1
if condition; then
程序段
elif condition;then
程序段
else
程序段
fi
-
语法2
case $变量 in:
"第一个变量内容")
程序段
;;
"第二个变量内容")
程序段
;;
*)
echo "404"
esac
循环语句
-
while
while condition ; do 程序段;done
-
until
until condition ; do 程序段;done
-
for
for var in [words...]; do 程序段; done
函数
-
语法1
funcName(){echo "abc";}
-
语法2
function funcName(){echo "abc";}
模块化
模块化的原理是在当前shell内执行函数文件(导入库)
source [函数库的路径]
常用命令
| 命令 | 使用 |
|---|---|
| grep | 查找错误日志:grep -n "ERROR" -A3 -B3 cloudfun.log |
| sort | 指定分隔符后以第三列进行排序: sort -t " " -k 3 |
| wc | 统计出现的行数、单词书、字符数、 wc -lwm |
| head | 查看前十行:head -n -10 cloudfun.log |
| tail | 等待追加内容:tail -f -n 10 cloudfun.log |
| cut | 对数据行的内容进行处理 cut -d " " -f 3 |
| find | 文件和目录查找 |
| xargs | 参数处理 |
| which | 查找命令路径 |
执行过程和原理
执行
- shell脚本一般以.sh结尾,这是约定;第一行需要指定用什么命令解释器来执行
#! /bin/bash
#! /user/bin/env bash
- 启动方式
文件名执行
./filename.sh
解释器执行
bash ./filename.sh
source 运行
source ./filename.sh
- 执行过程
- 字符解析
- shell展开,例如{1..3}解析为1 2 3
- 重定向,将stdin、stdout、stderr的文件描述符进行指向变更
- 执行命令
- 收集状态并返回
shell展开
- 大括号展开
{}
#字符串序列
a{b,c,d}e => abe ace ade
#表达序列式,数字可以用incr调整增量,字母不行
{1..5} => 1 2 3 4 5
{1..5..2} => 1 3 5
{a..e} => a b c d e
-
波浪号展开
~ -
参数展开
-
命令替换
-
数学计算
$((..)) -
文件名展开
*?[..]外壳文件名模式匹配