Shell学习的价值
- Linux服务器的基本操作和管理
- 前端Node.js服务的进程管理、问题排查、资源监控等运维操作
- 使用shell编写TCE、SCM、Docker脚本,完成服务编译和部署
shell基础概念
概念
- 终端 获取用户输出,显示运算结果的硬件设备
- tty(teletypeWrite) 和终端等价,在linux中是输入输出环境。是linux的一个终端,每个终端模拟器关联一个虚拟tty,和内核打交道
- 终端模拟器 关联虚拟tty的输入输出软件
- shell 处理来自终端模拟器的输入,解释执行之后输出结果给终端。
- Bash shell的一种具体的实现 (类比类和实例的体现)。0
发展历程
构成
-
解释器
- bash内置命令 . echo let 等
- GNU核心工具 ls mv mkdir cat
- 第三方库 node python 封装的模块
-
编程语言
- 变量
- 运算
- 语句
- 函数
shell还集成了软件开发中通用的设计模式及(管道和过滤器),具备控制流程,循环,变量,命令查找等机制,它可以采用丰富的GNU工具集,第三方或者内置的来作为命令的解释器。
语法和命令
变量
- 自定义类型:作用在当前shell
- 环境变量:作用在当前shell 和 子类 shell
- 系统环境变量: 作用在所有shell
- 父子shell的关系
自定义变量
page_size=1//等号的左右不能有空格_ls=ls//命令赋值给变量名let total=page_size*page_num//默认字符串,不会进行+运算export total//导出环境变量declare-给变量设定类型属性+取消变量的类型属性-a将变量声明为数组类型-i将变量声明为整数类型-x将变量声明为环境变量-r将变量声明为只读-p显示指定变量的被声明的类型
系统环境变量
配置文件加载
- Login shell
- 交互式
- 非交互式
- non-Login
运算符和引用
管道
- 管道与管道符
|,作用是将前一个命令的结果传递给后面的命令 - 语法:
cmd1|cmd2 - 要求:管道右侧的命令必须能接受标准输入才行,比如
grep,ls,mv等不能直接使用,但可以使用xargs预处理来传递结果 - 管道在发生错误的时候不会退出,可以使用
set -o pipefail设置shell 遇到错误退出
重定向
- 输出重定向
>:覆盖写入文件>>:追加写入文件2>:错误输出写入文件&>:正确和错误输出统一写入到文件中
- 输入重定向
<<<
判断命令
shell 中提供了 test、[、[[ 三中判断符号,可用于:
- 整数测试:
test condition - 字符串测试 :
[condition] - 文件测试 : `[[condition]]
注意
[ 、test是命令,只能使用自己支持的标志位,<、>、= 只能用来比较字符串 中括号的前后要有空格符,不然报错 中括号内的变量,最好要用引号引起来[[更丰富,在整型中支持< > =,在字符串比较中支持=~正则
分支语句
循环
-
- while
while condition ; do 程序段; done
- 2.until
until condition ; do 程序段; done
- 3.for
for var in [word...]; do 程序段;done
函数
funcName(){echo"abc";}function funcName() {echo "abc";}
注意:
- shell自上而下执行,所以变量的声明必须在使用前定义
- 1,$2` 来获取
- 函数内
return仅仅表示函数的执行状态,不代表函数的执行结果 - 返回结果一般使用
echo,printf, 在外面使用$(),''来获取结果 - 如果内有 return ,函数状态则是上一条命令的执行状态, 存储在
$?中 - 在函数内声明时,最好用
local来声明局部变量,不污染全局,或者在结尾采用unset在函数结尾释放该变量
模块化
模块化的原理是在当前 shell 内执行函数文件 ,方式 : source [函数库的路径]
常用命令
执行过程和原理
执行
- shell 脚本一般以 .sh 来结尾,也可以没有,这是一个约定。
#! /bin/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
-
- 波浪号展开
- 当前用户主目录
~ => $HOME - 指定用户主目录
~fred/foo => 用户fred 的 $HOME/foo - 当前工作目录
~+/foo => $PWD/foo - 上一个工作目录
~-/foo => ${$OLDPWD- '~-'}/foo
-
- 参数展开
-
- 命令替换
- 得到的结果替换包裹中的内容
$(...) 或 '...'
-
- 数学计算
echo $((1+2)) #3
-
- 文件名展开
- 当单词未被引号包裹,且其中出现了
* ? [字符,则shell会去按照正则去查找文件名并进行替换,若未找到则保持不变