1.shell概述:
拿到外层应用程序的命令,把命令解析成二进制编码,然后调用操作系统,由操纵系统去调用硬件来完成工作。
2.创造一个shell脚本
(1) 创造脚本,并写入hello world
[atguigu@hadoop101 datas]$ touch helloworld.sh
[atguigu@hadoop101 datas]$ vi helloworld.sh
在helloworld.sh中输入如下内容
#!/bin/bash
echo "helloworld"
(2) 运行脚本的方式
1:通过bash或者sh运行
1.1 相对路径运行:
[atguigu@hadoop101 datas]$ sh helloworld.sh
Helloworld
[atguigu@hadoop101 datas]$ bash helloworld.sh
Helloworld
1.2 绝对路径运行:
[atguigu@hadoop101 datas]$ sh /home/atguigu/datas/helloworld.sh
helloworld
[atguigu@hadoop101 datas]$ bash /home/atguigu/datas/helloworld.sh
Helloworld
2:直接打开文件运行
通过ll指令发现helloworld.sh并没有执行权限,所以需要先赋予权限
[atguigu@hadoop101 datas]$ chmod +x helloworld.sh
然后在运行脚本:
[atguigu@hadoop101 datas]$ ./helloworld.sh
Helloworld
3. shell变量
3.1 系统级别变量
$HOME、$PWD、$SHELL、$USER等
3.2 自定义变量
(1)通过等号来自定义变量。
// 定义变量A
[atguigu@hadoop101 datas]$ A=5
[atguigu@hadoop101 datas]$ echo $A
5
// 给A重新赋值
[atguigu@hadoop101 datas]$ A=8
[atguigu@hadoop101 datas]$ echo $A
8
// 撤销变量A
[atguigu@hadoop101 datas]$ unset A
[atguigu@hadoop101 datas]$ echo $A
(2)readonly的作用:
[atguigu@hadoop101 datas]$ readonly B=2
[atguigu@hadoop101 datas]$ echo $B
2
[atguigu@hadoop101 datas]$ B=9
-bash: B: readonly variable
(3)变量默认都是字符类型
[atguigu@hadoop102 ~]$ D="I love banzhang" //注意不要省略双引号
[atguigu@hadoop102 ~]$ echo $D
I love banzhang
[atguigu@hadoop102 ~]$ C=1+2
[atguigu@hadoop102 ~]$ echo $C
1+2 //注意这里不是3
(4)将变量提升至全局变量
[atguigu@hadoop101 datas]$ vim helloworld.sh
在helloworld.sh文件中增加echo $B
#!/bin/bash
echo "helloworld"
echo $B
输出打印:
[atguigu@hadoop101 datas]$ export B //把脚本中的B放到外面,提升至全局变量
[atguigu@hadoop101 datas]$ ./helloworld.sh
helloworld
2
3.3 特殊变量
3.3.1 $n
功能描述:
$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
3.3.2 $#:输出变量个数
3.3.3 $* $@:输出命令行中所有参数
举例:
ps.创建一个parm.sh文件,并在 param.sh中进行以下编写:
打开文件:
3.3.4 $?:判断脚本是否正确执行
[atguigu@hadoop101 datas]$ ./helloworld.sh
hello world
[atguigu@hadoop101 datas]$ echo $?
0
4. 运算符
常见运算符:+ - * / %
表达形式:“$((运算命令))”或“$[运算命令]”
[root@hadoop100 shells]# echo $[(1+2)*2]
6
5. 条件判断
表达形式【condition】
5.1 两个整数的比较
-lt | 小于(less than) |
-le | 小于等于(less equal) |
-eq | 等于(equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater equal) |
-ne | 不等于(Not equal) |
5.2 判断文件的权限
-r | 有读的权限(read) |
-w | 有写的权限(write) |
-x | 有执行的权限(execute) |
5.3 判断文件类型
-e | 文件存在(existence) |
-f | 文件存在并且是一个常规的文件(file) |
-d | 文件存在并是一个目录(directory) |
5.4 举例:
// 判断23是否大于22
[atguigu@hadoop101 datas]$ [ 23 -ge 22 ]
[atguigu@hadoop101 datas]$ echo $?
0
// 判断helloworld.sh文件是否有写入权限
[atguigu@hadoop101 datas]$ [ -w helloworld.sh ]
[atguigu@hadoop101 datas]$ echo $?
0
// 判断指定路径下的文件是否存在
[atguigu@hadoop101 datas]$ [ -e /home/atguigu/cls.txt ]
[atguigu@hadoop101 datas]$ echo $?
1
//多条件判断
// && 表示前一条命令执行成功时,才执行后一条命令
// || 表示上一条命令执行失败后,才执行下一条命令
[atguigu@hadoop101 ~]$ [ condition ] && echo OK || echo notok
OK
6.流程控制
6.1 if判断
(1)基本语句
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
(2)实操
在shells文件夹内创建一个if文件,并进行如下编写:
测试结果:
6.2 case语句
(1)基本语句
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
(2)实操:
创建一个case文件并编写,在里面写入如下代码:
测试结果:
6.3 for循环
(1)基本语句
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
(2)实操
创建一个for.sh文件,并在其中进行以下编辑:
测试结果:
6.4 while循环
(1)基本语句
while [ 条件判断式 ]
do
程序
done
(2)实操
创建一个while.sh文件并在其中写入:
测试结果:
7.读取控制台输入
7.1 基本用法
read(选项)(参数)
选项:
-t:指定读取值时等待的时间(秒)
-p:打印到控制台(print)
参数
变量:指定读取值的变量
7.2 举例
8.自定义函数
8.1 系统函数
(1)basename:提供路径可以把文件名给截出来
(2)dirname:截取路径
8.2 自定义函数
创建一个fun.sh并输入如下代码:
函数运行:
9. 正则表达式
9.1 常规的匹配方式
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep atguigu
9.2 常见的特殊字符
// 匹配以a开头的行
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep ^a
// 匹配以t结尾的行
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep t$
// 匹配以r开头,以r结尾的,中间有两个字母的
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep r..t
//(字母*) 代表这个字母可以出现0次一起上
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep ro*t
// 会匹配rt, rot, root, rooot, roooot等所有行
// [a,z]匹配a或z
// [a-z]匹配a到z之间的字符
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep r[a,b,c]*t
// 会匹配rat, rbt, rabt, rbact等等所有行
// 查找包含$的行
// 由于$是特殊字符,为了不引起歧义,加上转义符号\
[atguigu@hadoop102 datas]$ cat /etc/passwd | grep '\$' //必须加单引号
10. shell工具
10.1 cut:裁剪
1)基本用法
cut [选项参数] filename
说明:默认分隔符是制表符
选项参数说明
选项参数 | 功能 |
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符分割列 |
-c | 指定具体的字符 |
2)
举例1 :
创建一个cut文件,并在其中输入值:
[atguigu@hadoop101 datas]$ touch cut.txt
[atguigu@hadoop101 datas]$ vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le l
在cut.txt文件中切割出guan
[atguigu@hadoop101 datas]$ cat cut.txt | grep "guan" | cut -d " " -f 1
guan
举例2:选取系统PATH变量值,第2个“:”开始后的“所有”路径
[atguigu@hadoop102 datas]$ echo $PATH | cut -d: -f 2-
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin
举例3:取出此时的ip地址
10.2 awk:以空格进行切片,然后处理
(1)表达方式
awk [选项参数] ‘pattern1{action1} pattern2{action2}...’ filename
// 注意‘’与{}不要忘
(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列
awk -F: '/^root/{print $7}' passwd
//F:指的是以:进行分割
/^root/指的是以root开头,正则表达式必须带有//
passwd指的是该文件
(3)搜索passwd文件以root关键字开头的所有行,并输出该行的第1和第7列,中间以“,”号分割
awk -F: '/^root/{print $1","$7}' passwd //不要忘记,加“”
(4)只显示第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell;在最后一行添加"da"
awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "da"}' passwd
(5) 将passwd文件中的用户id增加数值1并输出
// 发现id都在第三列,把第三列取出,让他加1
awk -v i=1 -F: '{print $3+i}' passwd
// -v 的作用就是赋值,这里把i赋值为1
(6)awk中的内置变量
FILENAME | 文件名 |
NR | 切割后行的个数 |
NF | 切割后列的个数 |
例:统计passwd文件名,每行的行号,每行的列数
awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:" NF}' passwd
10.3 sort
1)基本语法:sort(选项)(参数)
选项 | 说明 |
-n | 按照数字排序(number) |
-r | 从大到小排序(reverse) |
-t | 设定分隔符 |
-k | 指定要排序的列 |
2)举例:
数据准备:
[atguigu@hadoop102 datas]$ touch sort.sh
[atguigu@hadoop102 datas]$ vim sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
按照“:”分割后的第三列倒序排序
[atguigu@hadoop102 datas]$ sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6