一、Shell的价值
-
熟悉Linux服务器的基本操作和管理。
-
帮助前端Node.js服务的进程管理、问题排查、资源监控等运维操作。
-
可以使用Shell编写TCE、SCM、Docker脚本,完成服务编译和部署。
二、Shell基础概念
2.1 基础概念
-
终端:获取用户输入,展示运算结果的硬件设备。
-
tty:teletypeWriter简称,等价于终端,在Linux中指输入/输出环境。
-
终端模拟器:关联虚拟tty的输入输出软件。
-
Shell:处理来自终端模拟器的输入,解释执行后的结果给终端。
-
Bash:Shell的一种具体实现。
2.2 发展历程
-
Ken Thonpson(贝尔实验室)在1971年为UNIX开发了第一个shell,称为V6 shell
-
Stephen Boume在贝尔实验室为V UNIX所开发的Bourne shell即sh
-
开源组织GUN为了取代Boume shell开发的Bourne-Again shell,即Bash
2.3 Shell 的构成
-
Shell不仅提供了与内核和设备交互的方法,还集成了软件开发中通用的设计模式(如管道、过滤器)。
-
Shell既是命令解释器,也是一门编程语言,作为解释器,它给用户提供了接口,通过丰富的GNU工具集实现各种功能。
三、Shell语法和命令
3.1 变量
-
自定义变量:作用在当前shell,用=声明,分字符串、整形、浮点型、日期型。
-
环境变量:作用在当前shell和子类shell,用export或declare -x声明。
-
系统环境变量:作用在所有shell,启动加载时自动声明。
父类Shell和子类Shell的关系如图:
3.2 变量声明
page_size=1 //等号的左右不能有空格
_ls=ls //命令赋值给变量名
let total=page_size*page_num //默认字符串,不会进行+运算
export total //导出环境变量
declare 【】
- -给变量设定类型属性
- +取消变量的类型属性
- -a 将变量声明为数组类型
- -i 将变量声明为整数类型
- -x 将变量声明为环境变量
- -r 将变量声明为只读
- -p 显示指定变量的被声明的类型
3.3 系统环境变量
- $0:表示当前执行的脚本或命令的名称
- $#:表示命令或脚本要处理的参数的个数
- $*:把所有的参数看成以空格分隔的一个字符串整体(单字符串)返回
- $?上条命令执行的状态码
- $PS1命令提示符
- $HOME用户主文件夹
- $PATH全局命令的搜索路径
3.4 运算符和引用
类型:算数运算符、逻辑运算符、比较运算符、引号、圆括号、命令连接、后台运行。
3.5 管道
-
管道与管道符|,作用是将前一个命令的结果传递给后面的命令。
-
语法:cmd1|cmd2
-
要求:管道右侧的命令必须能接受标准输入才行,比如 grep,ls,mv 等不能直接使用,但可以使用 xargs 预处理来传递结果。
-
管道在发生错误的时候不会退出,可以使用 set -o pipefail 设置shell 遇到错误退出。
3.6 重定向
重定向可以让我们的程序的标准输出、错误输出的信息重定向文件里,还可以将文件的内容代替键盘作为一种标准输入的方式。
①输出重定向
·> :覆盖写入文件
·>> :追加写入文件
·2> :错误输出写入文件
·&> :正确和错误输出统一写入到文件中
②输入重定向
·<
·<<
3.7 判断命令
shell中提供了test、 [ 、[[ 三种判断符号,可用于:
- 整数测试:test condition
- 字符串测试:[condition]
- 文件测试:[[condition]]
注意:
- 中括号前后要有空格符;
- [和test是命令,只能使用自己支持的标志位,<、>、=只能用来比较字符串
- 中括号内的变量,最好都是用引号括起来 -[[更丰富, 在整型比较中支持<、>、=,在字符串比较中支持=~正则
3.8 分支语句
3.9 循环语句
- while循环:while condition ; do 程序段; done
- until循环:until condition ; do 程序段; done
- for循环:for var in [word...]; do 程序段;done
3.10 函数
-
语法一:funcName(){echo "abc"}
-
语法二:function funcName(){echo "abc"}
注意:
- shell自上而下执行,函数必须在使用前定义。
- 函数获取变量和 shell script类似,0代表函数名,后续参数通过0代表函数名,后续参数通过0代表函数名,后续参数通过1、$2...获取。
- 函数内 return仅仅表示函数执行状态, 不代表函数执行结果。
- 返回结果一般使用 echo、 printf,在外面使用$()、'' 获取结果。
- 如果没有 return,函数状态是上一条命令的执行状态,存储在$?中。
3.11 模块化
·原理:在当前shell内执行函数文件
·方式:source [函数库的路径]
四、执行过程和原理
4.1 执行
shell 脚本一般以 .sh 来结尾,也可以没有,这是一个约定。 #! /bin/bash
启动方式:
-
文件名运行 ./filename.sh
-
解释器运行 bash ./filename.sh
-
source 运行 source ./filename.sh
4.2 shell展开
{1..3} 解析为 1 2 3
重定向,将stdin,stdout,stderr 的文件描述符进行指定变更
4.3 大括号展开
-
字符串序列 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
4.3 波浪号展开
-
当前用户主目录 ~ => $HOME
-
指定用户主目录 ~fred/foo => 用户fred 的 $HOME/foo
-
当前工作目录 ~+/foo => $PWD/foo
-
上一个工作目录
-/foo => {OLDPWD- '-'}/foo
4.4 文件名展开
当单词未被引号包裹,且其中出现了 * ? [ 字符,shell会去按照正则去查找文件名并进行替换,若未找到则保持不变。