一、Shell介绍
1、 定义:
- 在计算机科学中,shell(壳)是操作系统的壳,操作系统相对于shell来说为核
- shell是用户与操作系统之间的接口程序
- shell是一个命令解释器-shell自己有内置的命令集,shell脚本编程就是操作这些命令
2、shell 执行原理
- 首先检查是否为内部命令,否的话则在指定的搜索路径中检查是否为可执行的应用程序,否的话提示:未找到命令或不是内部或外部命令
3、学习命令行shell
- 通过命令形式操作数据或引用程序;
- 如:
windows -->cmd.exe
linux -->bash/..
- 提示:
- 我们通过常说的shell脚本编程就是指linux系统中的shell编程
- linux中的shell有很多种,如:sh/csh/ksh/…等,这里介绍shell编程最常用的bash shell
1. 查看默认shell类型
打开命令行执行:echo $SHELL
1). echo:显示输出指定内容
2). $SHELL:SHELL为变量名称,$为变量标识符
注意:$SHELL:为大写
2. 查看支持的shell类型
打开命令行执行:cat /etc/shells
1). cat:查看文件内容命令
2). /etc/shells:文件路径及文件名
4、查看shell的使用方式
1.通过命令行直接输入
说明:通过命令行模式输入命令并执行
如:
1). echo hello
2). echo 123
提示:通过命令行模式为单行执行,无法一次多行脚本执行
2.通过编辑脚本
说明:通过vi或vim来编辑脚本文件(.sh)(如果文件不存在则先创建空脚本文件在编辑文件)
提示:
- vi:编辑器
- vim:vi的升级版,完全兼容vi,添加新的特性,更适合编辑代码脚本,vi则多用于编辑文本【推荐 vim】
- 通过文件的方式执行,可以一次执行多行命令
二、 shell脚本规范
1.1 脚本创建
- 脚本创建工具
使用编辑器vim/vi来创建 如vim test01.sh
- 脚本命名
- 不能以数字开头;
- 脚本的名称尽量不为shell命令关键字
- 后缀名尽量为.sh
- 脚本命名最好有实际意义
- 脚本的内容
- 首行声明编译器类型 如:
#!/bin/bash
- 等号前后不含空格
- 成对内容一次写出来 如:{}、[]、’’、``、""
- [ ]内容前后留空格 如 [ name ]
- 变量的引用加双引号,大括号,"{name}"
- 脚本尽量不要使用中文(防止脚本在切换环境后,因编码问题导致乱码)
- shell脚本注释
说明:在脚本中注释行不被编译器所执行
作用:说明以下代码的作用,方便维护; - shell 注释分类
- 单行注释
说明:使用#号标识的行为单行注释;
如:
# 此行为单行注释
- 多行注释
说明:以:<<加指定注释符开头,以开头指定的注释符为结尾,中间区域为注释区
如:
1) :<<!
注释区域
注释区域
!
2) :<<hello
注释区域
注释区域
hello
1.2 脚本执行
说明:shell脚本被执行的几种方式
脚本执行方式
- bash test01.sh
–> bash、test01.sh都可以为绝对路径
如:/bin/bash /root/test01.sh
【推荐】 - /root/test01.sh
–> 运行test01.sh的绝对路径或./test01.sh (脚本必须有可执行权限) - source test01.sh
–> source命令也称为“点命令”,也就是“.”,是bash内部命令。
提示:
1). 当tes01.sh有可执行权限时,执行方式1和方式2是没有区别的,方式2 ./test01.sh(当前路径);
(执行文件所在目录不在path中,指定目录路径及脚本执行)
2). source功能:使Shell读入指定的Shell程序文件并依次执行文件中的所有语句;
(刚修改文件,立即生效,无需注销重新登录)
三、Shell变量
1. shell变量
1.1 什么是变量
说明:把指定字符串或计算结果赋值给一个名称,引用该名称可以获取到对应的字符串或值,
字符串或值可根据需求发生变化,而引用名称不变;(引用名称:就是我们所说的变量)
1.2 什么是shell变量
说明:在shell脚本中的引用变量;如果变量为自定义,那么自定义变量需要符合shell变量命名规范;
1.3 shell变量规范
- 变量名以英文字母或者下划线开头,但是不能以数字开头
(name=“xiaoming” 正确;_age=18 正确;1a=“error” 错误;) - 变量名区分大小写
(如:name="zhangsan"与NAME="李四"不同) - 变量名与等号之间,等号与变量值之间不要有空格
(如: name=“zhangsan”) - 使用$加变量名来使用变量的值
(如:echo $name) - 引用变量名与字符串相连时,需要添加空格做分隔,或者变量名加{}修饰
(如:echo $name hello;echo ${name}hello;)
提示:以上为自定义变量名称和引用时的规范,除了自定义变量外shell脚本还有其他类型变量
2. shell变量类型
2.1 本地变量
说明:
1). 定义的变量只能在系统的局部环境下生效;作用范围小
2). 本地变量细分又分**普通变量**和**命令变量**
普通变量:
说明:用户自定义的变量,变量值一般为指定数据或者运算结果;变量的赋值有以下三种方式
- 变量名=变量值 --> name=zhangsan
(变量值必须是一个整体,中间不能有空格;如:name=zhang san) - 变量名=‘变量值’ --> name=‘zhang san’
(值全部为字符串) - 变量名=“变量值” --> name=“zhang san $age”(age为:变量名)
(值为字符串,如果值内有其他变量,则解析变量,并将变量值作为输出数据)
提示:
1). 变量值 ‘’ 和 " " 区别: ‘’ 不能解析其内变量,"" 可以解析其内变量
2). 变量值为数字,不加引号,其他默认推荐使用【""】
命令变量
说明:用户自定义的变量,变量值为shell命令;变量的赋值有以下两种方式
- 变量名=‘命令’ --> list=‘ls’
(``:为反引号 Tab键与Esc键中间波浪线键;输入法为英文状态下) - 变量名= $ (命令) --> list= $ (ls)
(执行括号内命令,将执行结果赋值给变量名)
提示:
1 ) ``移植性高;如果命令之间有层级关系,$ () 使用起来直观的点;
2 ) `` 和$()各有优缺点,对于shell入门来说两种都一样,那种好记使用那种;
read 命令
说明:获取键盘输入的内容赋给指定的变量
格式:
1). read 变量名
2). read 变量名 变量名
参数:
-p 添加提示信息 --> 如:read -p "请输入要统计的目录:" str
2.2 全局变量
说明:全局变量又称环境变量,作用域可以为当前shell、当前用户、所有用户;可以通过命令来查看和设置全局变量;
- 查看全局变量
env --> 查看系统已存在的全局变量 - 定义全局变量
export 变量=值
提示:
1). 全局变量命名建议为大写
2.3 内置变量
说明:bash中特殊的变量(向脚本传递参数)
序号 | 变量 | 含义 |
---|---|---|
01 | $0 | 脚本名 |
02 | $1-$9 | 参数位置1-9 |
03 | $# | 位置参数的个数 |
04 | “$*” | 所有位置参数(作为单个字符串)“$1 $2 $3" --> 传递了一个参数 |
05 | $? | 返回值 0为执行成功 如:echo $? |
传参格式:
1). bash 脚本名 参数
2). bash 脚本名 参数 参数
调用格式:
1). $1-$9
2). $#
3. 变量查看方式
- echo $变量名 如:echo $name
- echo “$变量名” 如:echo " $ name"
- echo ${变量名} 如:echo ${name}
(被引用时使用,如:str=“hello ${name}”;外侧已有引号) - echo “${变量名}” 如:echo " $ {name}"
提示:
两种格式4中写法,如果值内引用则无引号
4. 取消变量
对自定义的变量,如果不使用时要及时进行取消,释放系统资源
格式:
unset 变量名 --> unset name
(unset:内建shell命令,作用取消变量或函数;name:变量名称(无$) )
5. 小知识-扩展【重定向】
说明:把运行结果保存到指定的文件中,正确的执行命令使用数字1,错误的命令使用数字2
格式:
1) 命令 [脚本] 1>result.txt 或 命令 [脚本] 1>>result.txt
2) 命令 [脚本] 2>result.txt 或 命令 [脚本] 2>>result.txt
提示:
>: 覆盖-新的内容覆盖之前老的内容
>>:追加-在老的内容后面追加新的内容
四、Shell流程控制语句
1.流程控制语句
1.1 什么是流程控制语句
说明:可以控制程序执行顺序的语句
1.2 为什么学习流程控制语句
- 需要判断条件成立则执行指定语句
- 能快速遍历列表
1.3 流程控制语句分类
- 条件分支控制语句
- 条件循环控制语句
- 条件分支控制语句
说明:条件满足则执行语句
2.条件分支控制语句 分类
2.1 if…else…条件分支
说明:如果条件成立,则执行then后面语句,否则执行else后面语句
格式:
if [ 条件 ]
then
语句块
else
语句块
fi
提示:
- [ ]中括号在shell中表示为表达式,表达式前后必须有空格;如
[ 1 -gt 0 ]
- 条件中有变量或字符串使用""括起来
- then可以和if语句写在一行,then语句之前需要添加; 如:
if [ 条件 ];then
- 结尾有关键字
fi
字符串比较 其他符号
序号 | 操作符 | 含义 |
---|---|---|
1 | == | 是否相等 |
2 | != | 不等于 |
3 | -z | 字符串为空 |
4 | -n | 字符串不为空 |
逻辑运算符
序号 | 表达 | 说明 |
---|---|---|
1 | -a [and] | 且 |
2 | -o [or] | 或 |
3 | ! | 非 |
数字比较 其他符号
序号 | 符号 | 说明 |
---|---|---|
1 | -eq [equal] | 等于 |
2 | -ne [no equal] | 不等于 |
3 | -gt [greate then] | 大于 |
4 | -ge [greate equal] | 大于等于 |
5 | -lt [less than] | 小于 |
6 | -le [less equal] | 小于等于 |
单括号与双括号
序号 | 括号 | 说明 |
---|---|---|
1 | () | 1. 命令组->在子shell中执行 如:(ls) 2. 命令替换->name=$(ls) 相当于 name=‘ls’ (反引号) 3.初始化数组->array=(1 2 3) |
2 | (()) | 1.整型计算->不能计算浮点型(小数) echo $((100-30))2.重定义变量值-> i=1;((i++)) |
3 | [] | 1.表达式-字符串比较运算符 -> ==和!=;不能比较整数,整数需要使用-lt…-gt;不能直接使用大于>和小于<,如果需要使用需要添加转义字符 \ 如 \ > 2. 表达式计算 --> i= [ [ [i+1] |
4 | [[]] | 与[]相同,但允许直接出现逻辑符号 如:==、!=、&&、<、> --> [[ $a != 1 && $a != 2 ]] |
5 | {} | 1. 文件列表进行拓展 -> 如 touch {test01,test02}.sh 2.标准变量输出; -> 读取变量使用 如:"${name}" |
逻辑判断-文件
序号 | 参数 格式 | 说明 |
---|---|---|
1 | -e filename | 文件是否存在,存在为真,不存在为假 |
2 | -d filename | 判断是否存在且为目录 |
3 | -f filename | 判断是否为普通文件 |
4 | -r filename | 是否存在且可读 |
5 | -w filename | 是否存在且可写 |
6 | -x filename | 是否存在且可执行 |
2.2 if…elif…条件分支
说明:如果条件成立,那么 then 后边的语句将会被执行;否则,执行 else 后边的语句
格式:
if [ 条件 ]
then
语句块
elif [ 条件 ]
then
语句块
...
else
语句块
fi
2.3 case条件分支
条件符合执行相应的代码块,类似于if..elif..语句
格式:
case 变量 in
值1 )
echo "语句块1"
;;
值2 )
echo "语句块2"
;;
值3 | 值4 )
echo "语句块3"
;;
...
* )
echo "语句块4-默认值"
;;
esac
提示:
1. 星号(*)相当于else,条件都不符合时执行;
2. 双分号(;;)是必须的,执行完相应语句块跳出程序;
3. 竖线(|)用于分割多个值,相当于 值1 or 值2 ;
4. 值可以为字符串、数字、区间值( [0-9] | [a-z] | [A-Z] )、组合词[aA][bB][cC]
4. 结尾必须有esac
3. 循环控制语句
说明:条件满足则循环,不满足则退出循环
3.1. for循环语句
遍历读取列表元素,列表元素遍历完毕,结束语句;
语法格式:
for 值 in 列表
do
执行语句
done
3.2 while 循环语句
说明:只要条件满足,就一直循环
语法格式
while [ 条件 ]
do
执行语句
done
提示:
1. 条件的类型:命令、字符串表达式、数字表达式
2. 中括号内前后有空格
五、Shell函数
1. 函数
说明:完成指定独立功能的代码段进行封装,需要调用才能被执行
1.1 shell函数常用方式
- 简单函数(无参)
说明:自定义函数,调用函数名
格式:
定义函数:
函数名(){
语句
...
}
调用函数:
函数名
- 带参函数(调用函数时带参数)
说明:调用函数名时带参数
格式
定义函数:
函数名(){
语句$n
...
}
调用函数:
函数名 参数
-
带参函数(执行脚本时调用参数)
说明:执行脚本时附带参数
格式
定义函数:
函数名(){
语句$n
...
}
调用函数:
函数名 $n