一.简介
1.定义
通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出
简单来说,shell就是一个用户跟操作系统之间的一个命令解释器
是一个功能相当强大的编程语言,易编写,易调试,灵活性强
最常用的shell是Bash,在日常工作中被广泛应用,也是大多数Linux操作系统默认的shell环境
2.功能
- 自动化批量系统初始化程序(update,软件安装,时区设置,安全策略)
- 自动化批量软件部署程序(LAMP,LNMP,Tomcat,LVS,Nginx)
- 应用管理程序(KVM,集群管理扩容,MySQL,DELLR720批量RAID构建)
- 日志分析处理程序(PV,UV,200,!200,top 100,grep/awk)
- 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
- 自动化管理程序(批量远程修改密码,软件升级,配置更新)
- 自动化信息采集及监控程序(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
- 自动化扩容(增加云主机 → 业务上线)
- 配合Zabbix信息采集
- 俄罗斯方块,打印三角形,打印五角星,打印圣诞树,运行小火车,排序算法实现
- 理论上可以做任何事(一切取决于业务需求)
3.特性
login shell:su - alice,/etc/profile,/etc/bashrc,~/.bash_profile,~/.bashrc
nologin shell:su alice,/etc/bashrc,~/.bashrc
命令和文件自动补齐
命令历史记忆功能:上下键,!number,!string,!$,!!,^R
别名功能:alias,unalias cp,~username/.bashrc,\cp -rf /etc/hosts
快捷键:^R,^D,^A,^E,^L,^U,^K,^S,^Q
前后台作业控制:&,nohup,^C,^Z,bg%1,fg%1,kill%3,screen
输入输出重定向:cat</etc/hosts,cat<<E0F,cat>file1<<E0F
管道:|tee,可以用来完成一些比较复杂的功能
命令排序:;不具备逻辑判断;&&,|| 具备逻辑判断
通配符(元字符):表示的不是本意
4.注意事项
命名一般为英文,大写,小写,后缀为.sh
不能使用特殊符号,空格
名称要写的一眼就能看出功能
首行需要以 #!/bin/bash 开头(指定解析器)
变量不能以数字,特殊符号开头,可以使用下划线,但不能使用破折号
5.运行方法
作为可执行程序运行
作为解释器参数运行
6.注释
单行注释:以#开头
多行注释::<,利用一个空命令接收要注释的命令行,不做任何事情,以此来达到注释的目的:命令行在起始 << EOF
和随后临近的 第一个 EOF
之间的内容都会被注释掉
7.步骤
①建立shell文件
②赋予shell文件可执行程序权限(使用chmod命令修改权限)
③执行shell文件(直接运行赋予权限后的二进制文件)
二.变量
1.分类
①环境变量
是所有shell程序都可以使用的变量
shell程序在运行时都会接收的一组变量,会影响到所有的脚本执行结果
常用的有:$HOME,$PWD,$SHELL,$USER等
基本语法
- 查看变量:echo $变量 env
- 取消变量:unset 变量
- 引用变量:$变量 或 ${变量}
- 定义变量:①export back_dir=/home/backup ②export back_dir1 将自定义变量转换成环境变量
作用范围
- 在当前shell和子shell有效
②自定义变量
基本语法
- 定义变量:变量 = 值
- 撤销变量:unset 变量
- 查看变量:echo $变量名 set(所有变量:包括自定义变量和环境变量)
- 声明静态变量:readonly 变量(注意:不能unset)
命名规则
- 可以由字母,数字和下划线组成,但是不能以数字开头,区分大小写,环境变量名建议大写
- 等号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
- 变量的值如果有空格,需要使用双引号或单引号括起来
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
作用范围
- 仅在当前shell中有效
③系统变量
主要在对参数判断和命令返回值判断时使用,包括脚本和函数的参数以及脚本核函数的返回值
$n:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
$#:获取所有输入参数个数,常用于循环
$!:上一个后台进程的PID
$*:代表命令行中所有的参数,把所有的参数看成一个整体
$@:代表命令行中所有的参数,不过把每个参数区别对待
$?:最后一次执行的命令返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了
2.赋值方式
显式赋值:变量名=变量值
read从键盘读入变量值:read 变量名
定义或引用变量时注意事项:① ' ':强引用 ② " ":弱引用,变量依然还是变量,而且会替换成相应的值 ③ ' ' :命令替换,等价于 $(),反引号中的shell命令会被先执行
3.运算
整数(90%以上)
- expr:+,-,\*,/,%
- $(()):+,-,*,/,%
- $[ ]:+,-,*,/,%
- let(用的最多)
小数
- echo "2*4" |bc
- echo "2^4" |bc
- echo "scale=2;6/4" |bc
- awk 'BEGIN{print 1/2}'
- echo "print 5.0/2" |python
注意事项
- 表达式与运算符之间必须有空格
- 完整的表达式要被两个 ` 包含(在Esc键下边那个键)
- 使用运算符需要搭配的常用工具有awk和expr(使用频繁)
4.内容的删除和替换
内容的删除
- url=www.sina.com.cn:定义变量
- echo ${#url}:获取变量值的长度
- echo ${url}:标准查看
- echo ${url#*.}:从前往后,最短匹配
- echo ${url##*.}:从前往后,最长匹配,贪婪匹配
- echo ${url%.*}:从后往前,最短匹配
- echo ${url%%.*}:从后往前,最长匹配,贪婪匹配
- echo ${url:0:5}:索引及切片
内容的替换
- url=www.sina.com.cn
- echo ${url/sina/baidu}:sina换成百度
- echo ${url/n/N}:n换成N
- echo ${url//n/N}:贪婪匹配
变量的替代
- ${变量名-新的变量值}
- 变量没有被赋值:会使用 “新的变量值” 替代
- 变量有被赋值(包括空值):不会被替代
- unset var1:删除变量
- echo ${var1}:未定义过,所以结果显示没有值
- echo ${var1-aaaaa}:赋值
- var2=111:定义变量
- echo ${var2-bbbbb}:因为var2有值,所以不会被替代
- var3= :有定义,但是是空值
- echo ${var3-ccccc}:有定义过,不会被替代,结果显示为空值
5.i++和++i(了解,基本用不到)
对变量的值没有影响
对表达式的值有影响:①i++:先赋值,再运算 ②++i:先运算,再赋值
三.条件测试
1.格式
test 条件表达式
[ 条件表达式 ] (注意前后要有空格)(建议使用)
[[ 条件表达式 ]]
2.常用的判断条件
两个整数之间比较
- = 字符串比较
- -lt 小于
- -le 小于等于
- -eq 等于
- -gt 大于
- -ge 大于等于
- -ne 不等于
按照文件权限进行判断
- -r 有读的权限
- -w 有写的权限
- -x 有执行的权限
按照文件类型进行判断
- -f 文件存在并且是一个常规的文件
- -e 文件存在
- -d 文件存在并且是一个目录
四.流程控制
1.if 判断
#单分支结构
if [ 条件判断式 ]
then 命令序列
fi
#双分支结构
if [ 条件判断式 ]
then 命令序列
else 命令序列
fi
#多分支结构
if [ 条件判断式 ]
then 命令序列
elif [ 条件判断式 ]
then 命令序列
else 命令序列
fi
注意事项
- [ 条件判断式 ],中括号与条件判断式之间必须有空格
- if 后要有空格
2.case 语句
case 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配后的命令序列
;;
esac
注意事项
- case行尾必须为单词 “in”,每一个模式匹配必须以右括号 “)” 结束
- 双分号 “;;” 表示命令序列结束,相当于java中的break
- 最后的 “*)” 表示默认模式,相当于java中的default
- 跳出循环的命令有:①break:允许跳出所有循环 ②continue:仅跳出当前循环,继续下一次循环
3.for 循环
#基本语法1
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
#基本语法2
for 变量 [ in 取值列表 ]
do
程序
done
注意事项
- in列表中可以包含替换,字符串和文件名等
- in列表是可选的,如果默认不使用,将会循环使用命令行中的位置参数
4.while until
while循环用于不断执行一系列命令,也用于从输入文件中读取数据
until循环执行一系列命令直到条件为true时停止
一般while循环优于until循环
#while语句结构:==当条件测试成立(条件测试为真),执行循环体
while 条件测试
do
程序
done
#until语句结构:==当条件测试成立(条件测试为假),执行循环体
until 条件测试
do
程序
done
五.数组
1.普通数组
只能使用整数作为数组索引
在bash下,仅支持一维数组,没有限定数组的大小
定义
- 一次赋一个值:数组名[下标]=变量值
- 一次赋多个值
查看数组
- declare -a
访问数组元素
- echo ${array1[0]}:访问数组中的第一个元素
- echo ${array1[@]}:访问数组中所有元素,等同于 echo ${array1[*]}
- echo ${#array1[@]}:统计数组元素的个数
- echo ${!array2[@]}:获取数组元素的索引
- echo ${array1[@]:1}:从数组下标1开始
- echo ${array1[@]:1:2}:从数组下标1开始,访问两个元素
遍历数组
- 通过数组元素的个数进行遍历
- 通过数组元素的索引进行遍历
2.关联数组
可以使用字符串作为数组索引
六.函数
1.系统函数
basename [string / pathname] [suffix]
- 功能:basename命令会删掉所有的前缀包括最后一个 “/” 字符,然后将字符串显示出来
- 选项:suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
dirname 文件绝对路径
- 功能:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
2.自定义函数
完成特定功能的代码片段(块)
在shell中定义函数可以使用代码模块化,便于复用代码
必须在调用函数之前,先声明函数,shell脚本是逐行运行的,不会像其他语言一样先编译
函数返回值,只能通过 $? 系统变量获得,可以显示加 :return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值 n(0-255)
function fun()表示有返回参数的函数
fun()表示无返回参数的函数
return可存在也可不存在,如果不加return,则默认最后一条语句的执行状态为函数执行状态的返回值
[ function ] funname[()]
{
action;
[return int;]
}
funname
七.内置命令
shift:使位置参数向左移动,默认移动1位,可以使用shift 2
exit:退出整个程序
break:结束当前循环,或跳出本层循环
continue:忽略本次循环剩余的代码,直接进行下一次循环
八.正则表达式
是一种字符模式,用于在查找过程中匹配指定的字符
在大多数程序里,正则表达式都被置于两个正斜杠之间
它将匹配被查找的行中任何位置出现的相同模式
在正则表达式中,元字符是最重要的概念
元字符
- 它表达的是不同于字面本身的含义
- shell元字符(也称为通配符):由shell来解析
- 正则表达式元字符:由各种执行模式匹配操作的程序来解析
正则表达式元字符
- \:转义符,将特殊字符进行转义,忽略其特殊意义
- ^:匹配行首,awk中,^则是匹配字符串的开始
- $:匹配行尾,awk中,$则是匹配字符串的结尾
- .:匹配除换行符\n之外的任意单个字符
- [ ]:匹配包含在 [字符] 之中的任意一个字符
- [^]:匹配 [^字符] 之外的任意一个字符
- [-]:匹配 [ ] 中指定范围内的任意一个字符,要写成递增
- ?:匹配之前的项1次或0次
- x\{m\}:字符x重复出现m次
- x\{m,\}:字符x重复出现m次以上
- x\{m,n\}:字符x重复出现m到n次
九.工具
1.cut
是在文件中负责剪切数据用的
cut命令从文件的每一行剪切字节,字符和字段并将其输出
基本用法
- cut [选项参数] filename
- 默认分隔符是制表符
选项参数说明
- -f:列号,提取第几列
- -d:分隔符,按照指定分隔符分割列
- -c:指定具体的字符
2.awk
是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入,一个或多个文件,或其它命令的输出
它支持用户自定义函数和动态正则表达式邓先进功能
它在命令行中使用,但更多是作为脚本来使用
处理文本和数据的方式:它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理
基本用法
- awk [options] 'commands' filenames
- awk [options] -f awk-script-file filenames
options
- -F:定义输入字段分隔符,默认的分隔符是空格或制表符(tab)
- -v:赋值一个用户定义变量
command
- BEGIN{}:行处理前
- {}:行处理
- END{}:行处理后
记录与字段相关内部变量
- $0:保存当前记录的内容
- NR:已读的记录数
- NF:浏览记录的域的个数(切割后,列的个数)
- FS:输入字段分隔符,默认空格
- OFS:输出字段分隔符
3.sed
是一种在线的,非交互式的编辑器,它一次处理一行内容
处理时,把当前处理的行存储在临时缓冲区中,称为模式空间;接着用sed命令处理缓冲区中的内容;处理完成后,把缓冲区的内容送往屏幕;接着处理下一行,这样不断重复,直到文件末尾
文件内容并没有改变,除非你使用重定向存储输出
主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
基本用法
- sed [选项参数] 'command' file(s)
- sed [选项参数] -f scriptfile file(s)
选项参数说明
- -e:直接在指令列模式上进行sed的动作编辑
- -i:直接编辑文件
命令功能描述
- a:新增,a的后面可以接字串,在下一行出现
- d:删除
- s:查找并替换
注
- sed和grep不一样,不管是否找到指定的模式,它的退出状态都是0
- 只有当命令存在语法错误时,sed的退出状态才是非0
- 和grep一样,sed在文件中查找模式时也可以使用正则表达式和各种元字符,正则表达式是括在斜杠间的模式,用于查找和替换
- sed支持的元字符有:①基本元字符:^,$,.,*,[ ],[^],\<\>,\(\),\{\} ②扩展元字符:?,+,{ },|,()
- 地址用于决定对哪些行进行编辑,地址形式可以是数字,正则表达式或二者的结合。如果没有指定地址,sed将处理输入文件中的所有行
4.sort
是在linux里非常有用,它将文件进行排序,并将排序结果标准输出
基本用法
- sort (选项)(参数)
选项参数说明
- -n:依照数值的大小排序
- -r:以相反的顺序来排序
- -t:设置排序时所用的分割字符
- -k:指定需要排列的列
参数
- 指定待排序的文件列表