前言:为何学习shell脚本?
1.运维人员需要;
2.开发者需要简单看懂shell程序;
3.如果学习大数据相关,需要会编写简单的shell脚本控制集群,提高开发效率.
备注:当然也可以学习Python.
1 shell脚本是什么?
1.1 shell概述
Shell是一个命令解释器,它接受应用程序/用户命令,然后调用操作系统内核。
它还是一个功能相当强大的编程语言,易编写,易调试,灵活性强。
1.2 shell解释器有几种?
shell脚本有六种,其中常用的是 /bin/sh /bin/bash,默认的是/bin/bash
2 shell简单入门
2.1 shell脚本格式
脚本以指定解释器开头:
#!/bin/bash
echo "hello world!"
# 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序
# echo 命令用于向窗口输出文本
执行方式:
第一种:
sh + 脚本相对路径,示例: sh helloworld.sh
sh + 脚本绝对路径,示例:sh home/shell/helloworld.sh
bash +脚本相对路径,示例: bash helloworld.sh
bash + 脚本绝对路径,示例:bash home/shell/helloworld.sh
第二种(日常使用这种):
./+脚本相对路径,示例:./helloworld.sh
脚本绝对路径,示例:home/shell/helloworld.sh
两者对比:
1.第一种,本质上是bash执行器帮我们执行,第二种本质上是自己执行,所以需要执行权限.
2.第一种执行方式,不需要在shell文件中写 #!/bin/bash.当然还是推荐写.
2.2 多命令处理演示
简单需求: 在 home/txt/路径下,创建zhangsan.txt文件,并在文件中添加"我喜欢李四"内容
#!/bin/bash
cd /home/txt
touch zhangsan.txt
echo "我喜欢李四" >> zhangsan.txt
结果:
3 shell中变量
3.1 shell中系统变量
3.1.1 常用的系统变量
- $HOME 查看用户家目录
- $PWD 查看当前的路径
- $SHELL 查看当前的shell解释器
- $USER 直接查看当前user
set命令:显示shell中所有的变量
系统变量演示:
3.1.2 自定义变量
1.基本语法
定义规则:
名称 | 方法 | 备注 |
---|---|---|
定义变量 | 变量=值 | 注意等号两侧没有空格 |
撤销变量 | unset 变量名 | / |
声明静态变量 | readonly 变量名 | 取消无法使用unset,重启虚拟机即可 |
变量提升为全局变量 | export 变量名 | 可供其他shell程序使用 |
3.1.3 特殊变量
1.特殊变量
特殊变量 | 功能 | 备注 |
---|---|---|
$n | $0代表执行的文件名, 1 − 9 代 表 第 一 到 第 九 个 参 数 , 10 以 上 数 字 用 大 括 号 包 含 , 如 1-9代表第一到第九个参数,10以上数字用大括号包含,如 1−9代表第一到第九个参数,10以上数字用大括号包含,如{10} | / |
$# | 描述获取所有输入参数个数,常用于循环 | / |
$* | 这个变量代表命令行中所有的参数,它把所有的参数看成一个整体 | 注意区别 |
$@ | 代表命令行中所有的参数,不过它把每个参数区分对待 | 注意区别 |
$? | 最后一次执行命令的返回状态,如果这个变量的值是0,证明上一个命令正确执行;如果这个变量的值为非0(具体哪个数字,由命令决定),则证明上一个命令执行不正确了。 |
2.特殊变量演示
$n演示:
$0代表执行的文件名,
1
−
9
代
表
第
一
到
第
九
个
参
数
,
10
以
上
数
字
用
大
括
号
包
含
,
如
1-9代表第一到第九个参数,10以上数字用大括号包含,如
1−9代表第一到第九个参数,10以上数字用大括号包含,如{10}
#!/bin/bash
echo $0 $1 $2 $3
实操结果:
$# 演示:
描述获取所有输入参数个数,常用于循环
#!/bin/bash
#!/bin/bash
echo $0 $1 $2 $3
echo $#
$# 演示实操结果:
$* 和 $@ 区别:
前面变量代表命令行中所有的参数,它把所有的参数看成一个整体
后面变量代表命令行中所有的参数,它把每个参数区分对待
#!/bin/bash
#!/bin/bash
echo $0 $1 $2 $3
echo $#
echo $*
echo $@
实操结果(后面有具体区别):
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210413175716946.png
$? 实操结果:
4 运算符
4.1 基本语法
(1). $((运算式)) 或者 $[运算式]
(2). expr(expr 运算符间要有空格,另外如果优先计算,则使用 "`"符号就是ESC下面那个键)
写法 | 含义 |
---|---|
+ | 加 |
- | 减 |
反斜杠* | 乘 |
/ | 除 |
% | 取余 |
实操演示:
5 条件判断案例
5.1 基本语法
[ condition ]
注意:condition前后要有空格.
5.2 常用判断条件
1.两个整数之间比较
符号 | 含义 |
---|---|
-lt | 小于( less than) |
-le | 小于等于(less equal) |
-eq | 等于(equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater equal) |
-ne | 不等于(Not equal) |
2.按照文件权限进行判断
符号 | 含义 |
---|---|
-r | 有读的权限(read) |
-w | 有写的权限(write) |
-x | 有执行的权限(execute) |
3.按照文件类型进行判断
符号 | 含义 |
---|---|
-f | 文件存在并且是一个常规的文件(file) |
-e | 文件存在(existence) |
-d | 文件存在并是一个(directory) |
4.多条件判断
&&表示前一条命令执行成功时,才执行后面一条命令,||表示上一条命令执行失败后,才执行下一条命令.
[ condition ] && echo ok || echo notok
[ condition && [ ] || echo notok
5.案例演示
(1).需求:45是否大于41?
(2).需求:查询某个文件是否有写入的权限?
(3).需求:判断某个文件是否存在?
6.流程控制(重点)
6.1 if
1.基本语法
#第一种写法
if [ 条件判断式 ];then
程序
fi
#第二种写法
if [ 条件判断式 ]
then
程序
fi
注意事项:
- [ 条件判断式 ],中括号和判断式之间必须有空格;
- if后面要有空格.
2. if 案例实操演示
第一种写法:
#!/bin/bash
if [$1 -eq 1 ];then
echo "nishuchuleshuzi1"
elif [$1 -eq 2 ];then
echo "nishuruleshuzi2"
fi
第二种写法:
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "nishuchuleshuzi1"
elif [ $1 -eq 2 ]
then
echo "nishuchuleshuzi2"
fi
3.if 输出:
6.2 case
1.基本语法
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
...省略其他分支
*)
如果变量的值都不是以上的值,则执行此程序
;;
easc
注意事项:
- case行尾必须为但是"in",每一个模式匹配必须以右括号")"结束;
- 双分号";;",表示命令行结束,相当于 Java 中的 break;
- 最后的"*)",表示模式模式,相当于 Java 中 default;
2. case 实操演示
#!/bin/bash
case $1 in
1)
echo "张三"
;;
2)
echo "李四"
;;
*)
echo "shiba"
;;
easc
3. case 输出
6.3 for 循环
1.基本语法1
for((初始值;循环控制条件;变量变化))
do
程序
done
2.for 实操演示
#!/bin/bash
s=0
for(( i=0;i<=100;i++))
do
s=$[$s+$i]
done
echo $s
3.for 案例一输出
4.for 基本语法2
for 变量 in 值1 值2 值3
do
程序
done
5. for 案例实操2
这里演示 $* 和 $@ 区别:
#!/bin/bash
for i in "$*"
do
echo "zhangsan xihuan $i"
done
for j in "$@"
do
echo "zhangsan xihuan $j"
done
6. for 案例二输出
6.4 while 循环
1.基本语法
while [ 条件判断式 ]
do
程序
done
注意:
1.while 后面有空格;
2.[ 条件判断式 ],条件判断式有空格;
2.while 实操演示
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo "$s"
3.while 输出
7.read读取控制台输入
7.1 基本语法
read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值等待的时间.
参数:
变量:指定读取值的变量名.
备注:这里只演示常用的参数,还有很多,具体可以查询详细的内容.
7.2 read 案例实操
#!/bin/bash
read -t 7 -p "input you name" NAME
echo $NAME
7.3 read 输出
8.函数
8.1 系统函数
1.basename 基本语法
basename [string/pathname] [suffix]
功能描述:basename 命令会删除所有的前缀包括最后一个"/"字符,然后将字符串显示出来.
选项:suffix 为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉.
2.basename 案例实操
3.dirname 基本语法
dirname 文件绝对路径
功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
4.dirname 案例实操
8.2 自定义函数
1.基本语法
[ function ]funname[()]
{
action;
[return int;]
}
funname
注意:
(1).必须在调用函数地方之前,先声明函数,shell脚本是逐行运行,不会像其他语言一样先编译;
(2).函数返回值,只能通过 $? 系统变量获得,可以显示加: return 返回,如果不加,将以最后一行命令运行结果,作为返回值. return 后跟数值 n(0~255)
2.案例实操
#!/bin/bash
function sum ()
{
s=0;
s=$[$1+$2]
echo $s
}
read -p "input you paramter1:"p1
read -p "input you paramter2:"p2
sum $p1 $p2
3.输出
9.shell工具(重点)
9.1 cut
1.概念和基本用法
cut的工作就是"剪",具体的说就是在文件中负责剪切数据用的,cut命令从文件的每一行剪切字节,字符和字段,
并将这些内容输出.
cut [选项参数] filename
2.选项参数说明
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符割裂 |
3.cut 案例实操
#cut.txt 文件
zhangsan lisi
wo wo
lai lai
le le
需求:切割 cut.txt 文件的第一列
# -d 表示用什么切割, -分表示切割第几列
cut -d " " 1 cut.txt
4. 输出
9.2 sed 工具
1.概念和基本用法
sed是一种流编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间",接着用sed命令处
理缓冲区中的内容,处理完成后,把缓存区的内容送往屏幕.接着处理下一行,这样不断重复,直到文件末尾.文件内容并没有
改变,除非你使用重定向存储输出.
sed [选项参数] 'commend' filename
2. 选项参数和命令功能描述
选项参数 | 功能 |
---|---|
-e | 直接在指令列模式上进行 sed 的动作编辑 |
命令 | 功能描述 |
---|---|
a | 新增,a的后面可以接字符串,在下一行出现 |
d | 删除 |
s | 查找并替换 |
(这里只列举常用的)
3.sed 案例实操
#文件准备
zhangsan lisi
wo wo
wangwu
lai lai
le le
需求:将 sed.txt 文件中的第二行删除并将 wo 替换成为 ni
# 这里的 g ,代表global
sed -e "3d" -e "s/wo/ni/g" sed.txt
4.案例实操
9.3 awk 工具
1.概念和基本用法
概念:一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,
切开的部分再进行分析处理.概念:一个强大的文本分析工具,把文件逐行的读入,
以空格为默认分隔符将每行切片,切开的部分再进行分析处理.
# pattern:表示awk在数据中查找的内容,就是匹配模式
# action:在找到匹配命令后执行的一系列命令
awk [选项参数] 'pattern1{action1} pattern2{action2}..' filename
2.选项参数说明
选项参数 | 功能 |
---|---|
-F | 指定输入文件拆分隔符 |
-v | 复制一个用户定义变量 |
3.案例演示
准备数据:
cp /etc/passwd ./
(1).需求一:搜素 passwd 文件以 root 关键字开头的所有行,并输出该行的第7列
awk -F : '/^root/ {print $7}' passwd
(2).需求二: 搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第1列和第7列,中间以","号分割?
awk -F : '/^root/ {print $1 "," $7}' passwd
(3).需求三:只显示passwd的第一列和第7列,以逗号分割,且在所有其那面添加列名 “zhangsan”,在最后一行添加"lisi"
awk -F : 'BEGIN{print "zhangsan"} {print $1 "," $7} {print "lisi"}' passwd
(4). 将 passwd 文件中用户 ID 增加数值 1 并输出
4.awk 内置的变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数 |
NF | 浏览记录的域的个数(切割后,列的个数) |
(1).需求:统计 passwd 文件名,每行的行号,每行的列数
(2).切割IP
(3).查询 sed.txt中空行所在的行号(面试题)
9.4 sort 排序
1.基本语法
sort命令在Linux里非常有用,它将文件进行排序,并将排序结果标准输出.
sort(选项)(参数)
2.选项参数说明
选项参数 | 说明 |
---|---|
-n | 依照数值大小排序 |
-r | 以相反的顺序排序 |
-t | 设置排序时所用的分隔字符 |
-k | 指定需要排序的列 |
参数说明:指待排序的文件列表
3.案例实操
数据准备:
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
(1).需求:按照":"分割后的第三列倒序排序