1 Shell概述
1.1 为什么要学习shell
1.2 shell概述
2 Shell解析器
3 Shell脚本入门
3.1 脚本格式
3.2 创建一个Shell脚本
3.3 多命令处理
4 Shell中的变量
4.1 系统变量
4.2 自定义变量
4.3 特殊变量:$n
4.4 特殊变量:$#
4.5 特殊变量$*
4.6 特殊变量$?
5 运算符
6 条件判断
1 Shell概述
1.1 为什么要学习shell?
- 需要看懂运维人员的编写的shell编程
- 偶尔会需要编写shell管理集群,从而提高开发效率
1.2 shell概述
Shell介于Linux内核与外层应用程序之间
Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核
Shell是一个强大的编程语言,易编写,易调试,灵活性强。
2. Shell解析器
- Linux提供的Shell解释器有
[root@hadoop ~]# sudo cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
- sh和bash的关系,sh是bash的软链接
[root@hadoop bin]# cd /bin/
[root@hadoop bin]# ll | grep bash
-rwxr-xr-x. 1 root root 964608 Oct 31 2018 bash
lrwxrwxrwx. 1 root root 10 Aug 21 2021 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root 6964 Oct 31 2018 bashbug-64
lrwxrwxrwx. 1 root root 4 Aug 21 2021 sh -> bash
- Centos默认的解释器是bash
看下shell的系统变量
[root@hadoop bin]# echo $SHELL
/bin/bas
3 Shell脚本入门
3.1 脚本格式
以#!/bin/bash开头
3.2 创建一个Shell脚本
- 创建一个shell脚本,,并输出helloworld
[fenfen@hadoop ~]$ mkdir datas
[fenfen@hadoop ~]$ cd datas
[fenfen@hadoop datas]$ pwd
/home/fenfen/datas
[fenfen@hadoop datas]$ touch helloworld.sh
[fenfen@hadoop datas]$ vim helloworld.sh
[fenfen@hadoop datas]$ ll
total 4
-rw-r--r-- 1 fenfen happy 38 Jul 26 11:07 helloworld.sh
- 写入脚本内容
#!/bin/bash
echo "helloworld fenfen"
- 执行shell脚本
用sh
[fenfen@hadoop datas]$ sh helloworld.sh
helloworld fenfen
用bash
[fenfen@hadoop datas]$ bash helloworld.sh
helloworld fenfen
来一个绝对路径看看
[fenfen@hadoop datas]$ bash /home/fenfen/datas/helloworld.sh
helloworld fenfen
[fenfen@hadoop datas]$ sh /home/fenfen/datas/helloworld.sh
helloworld fenfen
用./试试看,发现不行,原因是原来是通过sh或者bash解析器执行,但是现在是自己的权限执行,没有x权限
[fenfen@hadoop datas]$ ./helloworld.sh
-bash: ./helloworld.sh: Permission denied
[fenfen@hadoop datas]$ ll
total 4
-rw-r--r-- 1 fenfen happy 38 Jul 26 11:07 helloworld.sh
因此修改权限
[fenfen@hadoop datas]$ chmod 755 helloworld.sh
[fenfen@hadoop datas]$ ll
total 4
-rwxr-xr-x 1 fenfen happy 38 Jul 26 11:07 helloworld.sh
[fenfen@hadoop datas]$ ./helloworld.sh
helloworld fenfen
3.3 多命令处理
在/home/fenfen/目录下创建一个banzhang.txt在banzhang.txt文件中增加“I love lili”
- 创建shell脚本
[fenfen@hadoop datas]$ touch batch.sh
[fenfen@hadoop datas]$ vim batch.sh
- shell脚本内容
#!/bin/bash
cd /home/fenfen/
touch banzhang.txt
echo "I love lili" >> banzhang.txt
- 执行脚本并查看结果
[fenfen@hadoop datas]$ bash batch.sh
[fenfen@hadoop datas]$ cd /home/fenfen
[fenfen@hadoop ~]$ ll
total 4
-rw-r--r-- 1 fenfen happy 24 Jul 26 12:28 banzhang.txt
drwxr-xr-x 2 fenfen happy 43 Jul 26 12:28 datas
-rw-r--r-- 1 fenfen happy 0 Jul 25 03:49 ok.txt
[fenfen@hadoop ~]$ cat banzhang.txt
I love lili
4 Shell中的变量
4.1 系统变量
- 常用系统变量
- $HOME:查看用户地主目录
[fenfen@hadoop ~]$ echo $HOME
/home/fenfen
- $PWD:查看当前目录
[fenfen@hadoop ~]$ echo $PWD
/home/fenfen
- $SHELL:查看默认解析器
[fenfen@hadoop ~]$ echo $SHELL
/bin/bash
- #USER:查看当前用户
[fenfen@hadoop ~]$ echo $USER
fenfen
- 原理就是将这些封装为变量
4.2 自定义变量
- 基本语法:变量=值
[fenfen@hadoop ~]$ A=1
[fenfen@hadoop ~]$ echo $A
1
[fenfen@hadoop ~]$ A=2
[fenfen@hadoop ~]$ echo $A
2
- 注意:变量的值可以改变,再赋值就变啦
- A=1中间不给空格
- 撤销变量:unset 变量
[fenfen@hadoop ~]$ unset A
[fenfen@hadoop ~]$ echo $A
- 声明一个静态只读变量:readonly 变量
[fenfen@hadoop ~]$ readonly B=3
[fenfen@hadoop ~]$ echo $B
3
- 但是不给unset
[fenfen@hadoop ~]$ unset B
-bash: unset: B: cannot unset: readonly variable
- 变量定义规则
-
变量名称可能由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
- 等号两侧不能有空格
- 变量默认类型都是字符串类型,无法直接进行数值运算
[fenfen@hadoop ~]$ C=1+1
[fenfen@hadoop ~]$ echo $C
1+1
- 变量的值如果有空格,需要使用双引号和单引号括起来
[fenfen@hadoop ~]$ D="banzhang love lili"
[fenfen@hadoop ~]$ echo $D
banzhang love lili
- 全局变量
如果把变量提升为全局变量export,可供其他Shell程序使用
[fenfen@hadoop datas]$ echo $D
banzhang love lili
[fenfen@hadoop datas]$ vim helloworld.sh
- shell脚本中增加
#!/bin/bash
echo "helloworld fenfen"
echo $D
- 但是因为不属于同一个进程,并且D是局部变量,所以用shell打印不出
[fenfen@hadoop datas]$ ./helloworld.sh
helloworld fenfen
- 所以升级为全局变量就有了
[fenfen@hadoop datas]$ export D
[fenfen@hadoop datas]$ ./helloworld.sh
helloworld fenfen
banzhang love lili
4.3 特殊变量:$n
-
$n:n为数字,并且0表示该脚本名称,1-9表示第一个到第九个参数,十以上的参数需要用大括号包含
${10},一般不超过5个
- 实例
- 创建一个sh文件
[fenfen@hadoop datas]$ touch parameter.sh
[fenfen@hadoop datas]$ vim parameter.sh
- shell脚本写一个
#!/bin/bash
echo "$0 $1 $2 $3"
- 执行下,会出来$0
[fenfen@hadoop datas]$ bash parameter.sh
parameter.sh
- 给个参数执行
[fenfen@hadoop datas]$ bash parameter.sh banzhang
parameter.sh banzhang
[fenfen@hadoop datas]$ bash parameter.sh banzhang love lili
parameter.sh banzhang love lili
4.4 特殊变量:$
-
基本语法:$# 获取所有输入参数的个数,常常用于循环中
- 实例
[fenfen@hadoop datas]$ vim parameter.sh
- Shell脚本
#!/bin/bash
echo "$0 $1 $2 $3"
echo $#
- 执行包含$#的脚本结果
[fenfen@hadoop datas]$ bash parameter.sh
parameter.sh
0
- 给个参数
[fenfen@hadoop datas]$ bash parameter.sh banzhang love
parameter.sh banzhang love
2
4.5 特殊变量$*
- 基本语法
$*:这个变量代表命令行中所有的参数,把所有的参数看成一个整理
$@:这个变量也代表命令行中所有的参数,不过是把每个参数区分对待
- 实例
- 写入shell脚本
#!/bin/bash
#!/bin/bash
echo "$0 $1 $2 $3"
echo $#
echo $*
echo $@
- 执行看看,最后虽然结果一样,可是$@表示内核还是一个一个的
[root@hadoop datas]# bash parameter.sh banzhang loves lili
parameter.sh banzhang loves lili
3
banzhang loves lili
banzhang loves lili
4.6 特殊变量$?
- 基本语法:最后一次执行命令的返回状态。如果这个变量的值为0,表上上一个命令执行正确,如果这个变量的值为非0,则上一个命令不正确
- 实例
[root@hadoop datas]# ./helloworld.sh
helloworld fenfen
[root@hadoop datas]# echo $?
0
[root@hadoop datas]# $?
-bash: 0: command not found
[root@hadoop datas]# echo $?
127
5 运算符
- 基本语法
- $((运算式))
- $[运算式]
- expr +,-,*,/,% 加减乘除取余 expr运算符间要有空格
- 实例
[root@hadoop datas]# expr 3 + 2
5
[root@hadoop datas]# expr 3 \* 2
6
[root@hadoop datas]# expr 4 / 2
2
- 2+3先运算记得`一下
[root@hadoop datas]# expr 2 + 3 \* 4
14
[root@hadoop datas]# expr `expr 2 + 3` \* 4
20
- 使用[]计算
[root@hadoop datas]# s=$[(2+3)*4]
[root@hadoop datas]# echo $s
20
6 条件判断
- 基本语法:[ condition ] condition 前后要有空格哦
条件非空即为true,[]会返回false
- 常用判断条件
- 字符串比较
- -lt小于
- -le小于等于
- -eq等于
- -gt大于
- -ge 大于等于
- -ne不等于
- 文件权限判断
- -r 有读的权限
- -w有写的权限
- -x有执行的权限
- 按照文件类型进行判断
- -f 文件存在并且是一个常规文件file
- -e文件存在existence
- -d文件存在并且是一个目录directory
- 多条件判断
- &&表示前一条成功,才执行后一条
- ||表示前一条失败,才执行后一条
- 实例
- 23是否大于等于22
[root@hadoop datas]# [ 23 -ge 22 ]
[root@hadoop datas]# echo $?
0
[root@hadoop datas]# [ 23 -le 22 ]
[root@hadoop datas]# echo $?
1
- helloworld 是否具有写权限
[root@hadoop datas]# [ -w helloworld.sh ]
[root@hadoop datas]# echo $?
0
- 目录的文件是否存在
[root@hadoop datas]# [ -e /home/fenfen/datas ]
[root@hadoop datas]# echo $?
0
- 多条件判断
[root@hadoop datas]# [ 2 -gt 1 ] && echo OK || echo notok
OK
[root@hadoop datas]# [ 2 -gt 1 ] && [ ] || echo notok
notok