Linux-笔记10

#### Shell概述

- shell是一个程序,它连接了用户和Linux内核,它可以解释用户输入的命令传递给内核,让用户可以更加方便的使用Linux系统

- shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序

![1620489299709](C:\Users\zhiy_\AppData\Roaming\Typora\typora-user-images\1620489299709.png)

- shell具备编程的能力,shell也是一种语言,C,C++,java,Python,Go等
- 语言分为编译型语言,C,C++,Go,需要提前编译,编译语言都有编译器
- 解释型语言,shell,Python,php,不需要提前编译,一边执行,一边解释,每种解释型语言都有解释器
- shell语言支持大部分编程语言都具备的功能:if判断,for循环,变量,数组,函数,加减乘除,逻辑运算

#### 规范shell脚本组成

```shell
[root@test ~]# vim user.sh
#!/bin/bash(环境声明)
#注释信息
可执行代码…
```

#### 如何写好一个shell脚本

- 明确任务需求

- 按需求整理好每一个步骤,先做什么,后做什么

- 运行脚本,并根据运行结果排除错误

- 优化脚本并达到最终效果

#### 编写脚本

- 编写第一个脚本

```shell
[root@localhost ~]# vim hello.sh
#!/bin/bash
#hello word
echo hello word

#赋予执行权限
[root@localhost ~]# chmod u+x hello.sh

#执行脚本
[root@localhost ~]# /root/hello.sh
hello word
```

- 编写创建用户脚本

```shell
[root@localhost ~]# vim user.sh
#!/bin/bash
useradd abc
passwd abc

[root@localhost ~]# chmod u+x user.sh

#非交互
[root@localhost ~]# vim user.sh
#!/bin/bash
useradd yyyy
echo 1 | passwd --stdin yyyy

[root@localhost ~]# ./user.sh
更改用户 yyyy 的密码 。
passwd:所有的身份验证令牌已经成功更新。
```

- 编写批量查看脚本

```shell
#查看系统版本信息,查看系统内核信息,查看系统内存信息,查看系统网卡信息,查看当前主机名
[root@localhost ~]# vim info.sh
cat /etc/redhat-release
uname -r
free -h
ifconfig ens32
hostname

#赋予执行权限
[root@localhost ~]# chmod u+x info.sh

#执行脚本
[root@localhost ~]# ./info.sh
CentOS Linux release 7.6.1810 (Core)
3.10.0-957.el7.x86_64
total used free shared buff/cache available
Mem: 972M 480M 147M 16M 344M 260M
Swap: 2.0G 239M 1.8G
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::8903:cb8:127b:dbc8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:a0:e8:12 txqueuelen 1000 (Ethernet)
RX packets 230110 bytes 325471733 (310.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20635 bytes 1385581 (1.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

localhost.localdomain
```

- 编写配置本地yum源脚本

```shell
#编写搭建本地yum仓库脚本【版1,丢人版】
[root@localhost ~]# vim yum.sh
#!/bin/bash
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
rm -rf /etc/yum.repos.d/*
touch /etc/yum.repos.d/local.repo
echo "[local]" > /etc/yum.repos.d/local.repo
echo "name=local_centos" >> /etc/yum.repos.d/local.repo
echo "baseurl=file:///mnt/centos" >> /etc/yum.repos.d/local.repo
echo "enabled=1" >> /etc/yum.repos.d/local.repo
echo "gpgcheck=0" >> /etc/yum.repos.d/local.repo

#编写搭建本地yum仓库脚本【版2,正常版】
[root@localhost ~]# vim yum.sh
#!/bin/bash
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
mount -a
rm -rf /etc/yum.repos.d/*
echo "[local]
name=local_centos
baseurl=file:///mnt/centos
enabled=1
gpgcheck=0" > /etc/yum.repos.d/local.repo

#编写搭建本地yum仓库脚本【升级版】
[root@localhost ~]# vim yum.sh
#!/bin/bash
echo "正在配置本地yum仓库..."
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos &> /dev/null
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
mount -a
rm -rf /etc/yum.repos.d/*
echo "[local]
name=local_centos
baseurl=file:///mnt/centos
enabled=1
gpgcheck=0" > /etc/yum.repos.d/local.repo
echo "本地yum仓库配置以完成..."
yum clean all &> /dev/null
yum repolist | tail -1
echo "仓库软件包数量"

#执行脚本
[root@localhost ~]# ./yum.sh
正在配置本地yum仓库...
本地yum仓库配置以完成...
repolist: 4,021
仓库软件包数量
```

#### 脚本的执行方式

- 执行一个脚本的方法有很多种
- 方法一:赋予脚本执行权限后,可用绝对路径或者当前路径执行
- 方法二:调用解释器执行脚本文件

```shell
#绝对路径执行脚本
[root@localhost ~]# /root/hello.sh

#相对路径执行脚本
[root@localhost ~]# ./hello.sh

#去除执行权限
[root@localhost ~]# chmod u-x hello.sh

#执行脚本
[root@localhost ~]# /root/hello.sh
-bash: /root/hello.sh: 权限不够

[root@localhost ~]# ./hello.sh
-bash: ./hello.sh: 权限不够

#调用解释器执行脚本
[root@localhost ~]# bash hello.sh
hello word

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@localhost ~]# sh hello.sh
hello word
[root@localhost ~]# tcsh hello.sh
hello word
[root@localhost ~]# csh hello.sh
hello word
```

#### 常用特殊符号补充

- “ “ #双引号,引用整体

- ‘ ’ #单引号,引用整体并取消所有特殊字符含义

- $[] #四则运算(+ - * / % 取余数)

- $() #将命令的输出结果作为参数

- #反撇 `` 将命令的输出结果作为参数

```shell
#引用整体,不屏蔽特殊符号的功能
[root@localhost ~]# echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

#引用整体,屏蔽特殊符号的功能
[root@localhost ~]# echo '$PATH'
$PATH

#没有特殊符号单引双引都可以
[root@localhost ~]# echo "xxoo"
xxoo
[root@localhost ~]# echo 'xxoo'
xxoo

#四则运算
[root@localhost ~]# echo $[1+1]
2
[root@localhost ~]# echo $[1+5]
6
[root@localhost ~]# echo $[10-5]
5
[root@localhost ~]# echo $[10*5]
50
[root@localhost ~]# echo $[10/5]
2
[root@localhost ~]# echo $[1+3+4+5+7]
20
[root@localhost ~]# echo $[10/3]
3
[root@localhost ~]# echo $[10%3]
1

#$()取命令结果作为参数
root@localhost ~]# touch $(date +%F)-abc.txt
2021-05-09-abc.txt

#``取命令结果作为参数
[root@localhost ~]# touch `date +%F`-xxoo.txt
2021-05-09-xxoo.txt
```

#### 变量

- 以固定的名称存放可能变化的值,提高脚本的灵活度来适应多变的环境

- 定义变量:变量名=变量值,如:a1=abc(等号两边不要有空格)

- 取消变量:unset 变量名

- 定义变量注意事项:

- 变量名由字母/数字/下划线组成,区分大小写,不能以数字开头,不要使用命令和特殊符号

- 若指定的变量名已经存在,相当于为此变量重新赋值

```shell
root@localhost ~]# xx=haha

[root@localhost ~]# echo $xx
haha

[root@localhost ~]# xx=abcd
[root@localhost ~]# echo $xx
abcd

[root@localhost ~]# xx=5
[root@localhost ~]# echo $xx
5
[root@localhost ~]# echo $[xx+5]
10

#通过变量定义用户名
[root@localhost ~]# vim user.sh
#!/bin/bash
user=wangxin
useradd $user
echo 1 | passwd --stdin $user

[root@localhost ~]# ./user.sh
更改用户 wangxin 的密码 。
passwd:所有的身份验证令牌已经成功更新。

[root@localhost ~]# vim user.sh
#!/bin/bash
user=sdd
useradd $user
echo 1 | passwd --stdin $user

[root@localhost ~]# ./user.sh
更改用户 sdd 的密码 。
passwd:所有的身份验证令牌已经成功更新。

[root@localhost ~]# vim user.sh
#!/bin/bash
user=panghu
useradd $user
echo "用户$user创建成功"
echo 1 | passwd --stdin $user &> /dev/null
echo "用户$user密码设置成功"

[root@localhost ~]# ./user.sh
用户panghu创建成功
用户panghu密码设置成功
```

#### read标准输入取值

- read 读取用户在键盘上输入的内容,并把内容存放在变量里,可以降低脚本的使用难度

- 命令格式:read -p “提示信息” 变量名

```shell
[root@localhost ~]# vim user.sh
#!/bin/bash
read -p '请输入用户名:' user
useradd $user
echo "用户$user创建成功"
read -p '请设置用户密码:' pass
echo $pass | passwd --stdin $user &> /dev/null
echo "用户$user密码设置成功"

[root@localhost ~]# ./user.sh
请输入用户名:wuhan
用户wuhan创建成功
请设置用户密码:1
用户wuhan密码设置成功

[root@localhost ~]# ./user.sh
请输入用户名:liangjing
用户liangjing创建成功
请设置用户密码:xxoo
用户liangjing密码设置成功
```

#### 变量种类

- 环境变量:变量名一般都大写,用来设置用户/系统环境
- 位置变量:bash内置,存储执行脚本时提供的命令参数
- 预定义变量:bash内置,可直接调用的特殊值,不能直接修改
- 自定义变量:用户自定义
- env 命令查看系统所有环境变量
- set 命令查看系统所有变量,包括用户自定义变量

- 环境变量

```shell
[root@localhost etc]# env
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=zh_CN.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
SSH_CONNECTION=192.168.0.1 51791 192.168.0.100 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
DISPLAY=localhost:10.0
_=/usr/bin/env
OLDPWD=/root

#获取变量值
[root@localhost etc]# echo $SHELL
/bin/bash

[root@localhost ~]# echo $PWD
/root

#查看系统所有变量
[root@localhost ~]# set
[root@localhost ~]# set | grep $a
```

- 位置变量

$0 #脚本名称

$1 #第一个参数

$2 #第二个参数

$3 #第三个参数

$4 #第四个参数

$n… #第n个参数

- 预定义变量

$0 #代表脚本本身

$* #显示所有参数内容

$# #显示有多少个参数

$? #显示上一条命令的执行结果(0代表正确,非0代表错误)

$$ #显示脚本进程号(PID)

```shell
[root@localhost ~]# vim test.sh
#!/bin/bash
echo $0
echo $1
echo $2
echo $3
echo $*
echo $#
echo $$
echo $?

#赋予执行权限,执行脚本
[root@localhost ~]# ./test.sh xx oo dd
./test.sh $0
xx $1
oo $2
dd $3
xx oo dd $*
3 $#
15594 $$
0 $?
```

#### 判断文件状态

- -e #判断文档(文件/目录)是否存在,存在为真
- -d #判断目录是否存在,存在为真
- -f #判断文件是否存在,存在为真
- -r #可读为真
- -w #可写为真
- -x #可执行为真

```shell
#判断文档是否存在
[root@localhost ~]# [ -e /etc/ ]
[root@localhost ~]# echo $?
0 #为真

#判断目录是否存在
[root@localhost ~]# [ -d /opt ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ -d /etc/passwd ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ -f /etc/passwd ]
[root@localhost ~]# echo $?
0

#判断是否可读(以当前用户身份判断)
[root@localhost ~]# [ -r /etc/passwd ]
[root@localhost ~]# echo $?
0

#判断是否可写
[root@localhost ~]# [ -w /etc/passwd ]
[root@localhost ~]# echo $?
0

#判断是否可执行
[root@localhost ~]# [ -x /etc/passwd ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# ll /etc/passwd
-rw-r--r--. 1 root root 3294 5月 9 16:43 /etc/passwd
```

#### 整数比较

- -gt #大于

- -ge #大于等于

- -eq #等于

- -lt #小于

- -le #小于等于

- -ne #不等于

```shell
[root@localhost ~]# [ 1 -gt 1 ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ 1 -eq 1 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 1 -ge 1 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 1 -ge 2 ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ 1 -lt 2 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 1 -le 2 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 1 -le 10 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 10 -le 10 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 1 -ne 2 ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ 2 -ne 2 ]
[root@localhost ~]# echo $?
1
```

#### 字符串对比

- == #相等
- != #不相等

```shell
[root@localhost ~]# [ root == xxoo ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ root == $USER ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ $USER == root ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ abc == bcd ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ abc != bcd ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ $USER != root ]
[root@localhost ~]# echo $?
1
```

#### 常用数值运算方式

- $[] #四则运算(+ - * / % 取余数)
- $(()) #数值运算工具
- expr #数值运算工具
- let #数值运算工具

```shell
[root@localhost ~]# echo $[10+5]
15
[root@localhost ~]# echo $[10-5]
5
[root@localhost ~]# echo $[10*5]
50
[root@localhost ~]# echo $[10/5]
2
[root@localhost ~]# echo $[10%3]
1

#$(())做数值运算
[root@localhost ~]# echo $((10+5))
15
[root@localhost ~]# echo $((10-5))
5
[root@localhost ~]# echo $((10*5))
50
[root@localhost ~]# echo $((10/5))
2
[root@localhost ~]# echo $((10%3))
1

#expr做数值运算
[root@localhost ~]# echo expr 2+3
expr 2+3
[root@localhost ~]# echo `expr 2+3`
2+3

#要求每一部分都要有空格
[root@localhost ~]# echo `expr 2 + 3`
5
[root@localhost ~]# echo `expr 10 - 3`
7

#当进行乘法运算时,需要实用“\”转义掉*的特殊功能
[root@localhost ~]# echo `expr 10 * 3`
expr: 语法错误

[root@localhost ~]# echo `expr 10 \* 3`
30
[root@localhost ~]# echo `expr 10 / 3`
3

#let做数值运算
[root@localhost ~]# let 1+1

#需要将运算的结果赋予一个变量存储
[root@localhost ~]# let x=1+1
[root@localhost ~]# echo $x
2
[root@localhost ~]# let a=10+5
[root@localhost ~]# echo $a
15

#通过变量的值进行运算
[root@localhost ~]# let b=a+x
[root@localhost ~]# echo $b
17

#let简写表达式 #let完整表达式
let i++ let i=i+1
[root@localhost ~]# i=10
[root@localhost ~]# let i++
[root@localhost ~]# echo $i
11

let i-- let i=i-1
[root@localhost ~]# let i--
[root@localhost ~]# echo $i
10

let i+=2 let i=i+2
[root@localhost ~]# let i+=2
[root@localhost ~]# echo $i
12

let i-=2 let i=i-2
[root@localhost ~]# let i-=2
[root@localhost ~]# echo $i
10

let i*=2 let i=i*2
[root@localhost ~]# let i*=2
[root@localhost ~]# echo $i
20

let i/=2 let i=i/2
[root@localhost ~]# let i/=2
[root@localhost ~]# echo $i
10

let i%=2 let i=1%2
[root@localhost ~]# let i%=3
[root@localhost ~]# echo $i
1
```

#### 字符串判断

- -z #字符串的值为空为真
- -n #字符串的值非空为真(相当于 ! -z)

```shell
#判断文件为空为真
[root@localhost ~]# [-z /etc/passwd]
bash: [-z: 未找到命令...

#判断时每一部分要有空格
[root@localhost ~]# [ -z /etc/passwd ]
[root@localhost ~]# echo $?
1

#判断文件非空为真
[root@localhost ~]# [ -n /etc/passwd ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ -z $i ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ -n $i ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ ! -z $i ]
[root@localhost ~]# echo $?
0
```

#### 条件判断结构

- 当条件满足时执行什么操作,当条件不满足时执行什么操作

- && #逻辑与(并且)

- || #逻辑或(或者)

- ; #条件之间没有逻辑关系

```shell
A && B #当A命令执行成功后才会执行B,如果A执行失败则B不执行
#判断存在且是文件执行拷贝操作(并且关系)
[root@localhost ~]# [ -f /etc/passwd ] && cp /etc/passwd /opt
[root@localhost ~]# ls /opt
abc.tar.bz2 passwd

#第一条命令执行失败,后边命令不执行
[root@localhost ~]# [ -f /etc/xxoo ] && cp /etc/passwd /opt
[root@localhost ~]# [ -f /etc/xxoo ] && cp /etc/xxoo /opt
[root@localhost ~]# ls /opt

A || B #当A命令执行失败后才会执行B,如果A执行成功则B不执行
#前便命令执行失败,后边命令则执行
[root@localhost ~]# [ -f /etc/xxoo ] || touch /opt/xxoo.txt
[root@localhost ~]# ls /opt
abc.tar.bz2 passwd xxoo.txt

#前边命令执行成功,后便命令则不执行
[root@localhost ~]# [ -f /etc/fstab ] || touch /opt/fs.txt
[root@localhost ~]# ls /opt

A ; B #执行A命令后执行B,两者没有逻辑关系
[root@localhost ~]# touch /mnt/xx.txt ; touch /opt/xx.txt
[root@localhost ~]# ls /mnt
centos xx.txt
[root@localhost ~]# ls /opt
abc.tar.bz2 abc.txt fs.txt pass.txt passwd xxoo.txt xx.txt
[root@localhost ~]# touch /opt/oo.txt ; rm -rf /opt/*
[root@localhost ~]# ls /opt
[root@localhost ~]# touch /opt/oo.txt ; rm -rf /opt/* ; touch /opt/xx.txt ; rm -rf /mnt/xx.txt
[root@localhost ~]# ls /opt
xx.txt
[root@localhost ~]# ls /mnt/
```

#### if 条件判断结构

- if 单分支语句,只能判断对,不能判断错

```shell
#第一种语法结构
if [条件判断];then
条件成立时,执行的命令
fi

#第二种语法结构
if [条件判断]
then
条件成立时,执行的命令
fi

#if单分支示例
[root@localhost yunwei]# vim if1.sh
#!/bin/bash
if [ -n /etc/passwd ];then
echo "非空"
fi

[root@localhost yunwei]# chmod u+x if1.sh
[root@localhost yunwei]# ./if1.sh
非空

#只能判断对,不能判断错
[root@localhost yunwei]# vim if1.sh
#!/bin/bash
if [ -z /etc/passwd ];then
echo "非空"
fi
```

- if 双分支语句

```shell
if [条件判断];then
条件成立时,执行命令a
else
条件不成立时,执行命令b
fi

#if双分支示例
[root@localhost yunwei]# vim if2.sh
#!/bin/bash
if [ -z /etc/passwd ];then
echo '空值'
else
echo '非空'
fi

[root@localhost yunwei]# chmod u+x if2.sh
[root@localhost yunwei]# ./if2.sh
非空

#编写参数字的脚本,让计算机产生一个0-9随机数
#$RANDOM环境变量,里边存放的是0-65535之间的随机数
[root@localhost yunwei]# echo $RANDOM
28484
[root@localhost yunwei]# echo $RANDOM
5440
[root@localhost yunwei]# echo $RANDOM
29651
[root@localhost yunwei]# echo $RANDOM
21747
[root@localhost yunwei]# echo $RANDOM
24494

#实用$RANDOM的值对10取余
[root@localhost yunwei]# echo $[RANDOM%10]
4
[root@localhost yunwei]# echo $[RANDOM%10]
2
[root@localhost yunwei]# echo $[RANDOM%10]
5
[root@localhost yunwei]# echo $[RANDOM%10]
3
[root@localhost yunwei]# echo $[RANDOM%10]
9
[root@localhost yunwei]# echo $[RANDOM%10]
1
[root@localhost yunwei]# echo $[RANDOM%10]
0
[root@localhost yunwei]# echo $[RANDOM%10]
3
[root@localhost yunwei]# echo $[RANDOM%10]
2

#编写猜数字脚本
[root@localhost yunwei]# vim if3.sh
#!/bin/bash
read -p '请输入0-9之间的随机数:' num
num1=$[RANDOM%10]
if [ $num -eq $num1 ];then
echo "恭喜你才对了,奖励一个哇塞女孩!"
else
echo "猜错了,请继续努力,奖品是一个哇塞女孩!"
echo "正确的结果为$num1"
fi

[root@localhost yunwei]# chmod u+x if3.sh
root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:1
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为6

[root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:7
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为3

[root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:3
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为2

[root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:0
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为5

[root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:9
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为2

[root@localhost yunwei]# ./if3.sh
请输入0-9之间的随机数:5
猜错了,请继续努力,奖品是一个哇塞女孩!
正确的结果为7

#安装软件包脚本
root@localhost yunwei]# vim if4.sh
#!/bin/bash
if [ `rpm -q vsftpd &> /dev/null ; echo $?` -eq 0 ];then
systemctl start vsftpd
systemctl enable vsftpd &> /dev/null
echo "软件包以安装,并设置随机自启"
else
yum -y install vsftpd &> /dev/null
systemctl start vsftpd
systemctl enable vsftpd &> /dev/null
echo "软件包以重新安装上,并设置随机自启"
fi

[root@localhost yunwei]# chmod u+x if4.sh
[root@localhost yunwei]# ./if4.sh
软件包以重新安装上,并设置随机自启
```

- if 多分支语句

```shell
if [条件判断1];then
条件1成立时,执行命令a
elif [条件判断2];then
条件2成立时,执行命令b
elif [条件判断3];then
条件3成立时,执行命令c
...省略更多条件
else
所有条件都不成立时,执行命令d
fi

#编写判断成绩脚本
[root@localhost yunwei]# vim if5.sh
#!/bin/bash
read -p "请输入你的成绩(满分为100分):" num
if [ $num -ge 90 ];then
echo "成绩非常优秀!,奖励一个肤白貌美大长腿,绝世容颜哇塞女孩"
elif [ $num -ge 80 ];then
echo "比较优秀"
elif [ $num -ge 70 ];then
echo "一般一般"
elif [ $num -ge 60 ];then
echo "勉强及格"
else
echo "收拾收拾,回家种地去吧!"
fi

[root@localhost yunwei]# chmod u+x if5.sh
[root@localhost yunwei]# ./if5.sh
请输入你的成绩:66
勉强及格
[root@localhost yunwei]# ./if5.sh
请输入你的成绩:55
收拾收拾,回家种地去吧!
[root@localhost yunwei]# ./if5.sh
请输入你的成绩:0
收拾收拾,回家种地去吧!
[root@localhost yunwei]# ./if5.sh
请输入你的成绩:99
成绩非常优秀!,奖励一个肤白貌美大长腿,绝世容颜哇塞女孩
[root@localhost yunwei]# vim if5.sh
[root@localhost yunwei]# ./if5.sh
请输入你的成绩(满分为100分):100
成绩非常优秀!,奖励一个肤白貌美大长腿,绝世容颜哇塞女孩
[root@localhost yunwei]# ./if5.sh
请输入你的成绩(满分为100分):90
成绩非常优秀!,奖励一个肤白貌美大长腿,绝世容颜哇塞女孩
[root@localhost yunwei]# ./if5.sh
请输入你的成绩(满分为100分):200
成绩非常优秀!,奖励一个肤白貌美大长腿,绝世容颜哇塞女孩
```

#### case条件判断结构

- case从变量中取值,如果变量中的值与预设的值匹配,则执行对应的命令

```shell
#case语法结构
case $变量名 in
值1)
执行的命令xx;; #如果变量中的值等于值1,则执行的命令
值2)
执行的命令yy;; #如果变量中的值等于2,则执行的命令
...省略其他分支
*)
执行的命令zz;; #如果变量中的值都不是以上的值,则执行的命令
esac


[root@localhost yunwei]# vim case.sh
#!/bin/bash
read -p "请输入您喜爱的老师(仓老师|波多老师|小泽老师):" xxoo
case $xxoo in
仓老师)
echo "又白又嫩又水润,上楼右转1号房间!";;
波多老师)
echo "前凸后翘,波涛汹涌,上楼右转2号房间!";;
小泽老师)
echo "肤白貌美大长腿,上楼右转3号房间!";;
*)
echo "老师休假了";;
esac

[root@localhost yunwei]# chmod u+x case.sh
[root@localhost yunwei]# ./case.sh
请输入您喜爱的老师(仓老师|波多老师|小泽老师):仓老师
又白又嫩又水润,上楼右转1号房间!
[root@localhost yunwei]# ./case.sh 波多老师
请输入您喜爱的老师(仓老师|波多老师|小泽老师):波多老师
前凸后翘,波涛汹涌,上楼右转2号房间!
[root@localhost yunwei]# ./case.sh
请输入您喜爱的老师(仓老师|波多老师|小泽老师):小泽老师
肤白貌美大长腿,上楼右转3号房间!
[root@localhost yunwei]# ./case.sh
请输入您喜爱的老师(仓老师|波多老师|小泽老师):穆穆老师
老师休假了
```

#### for循环

- for循环处理,根据变量的取值,重复执行xx命令

```shell
#for循环语法结构
for 变量名 in 值1 值2 值3 值N...
do
执行的命令
done

#编写循环创建用户脚本
[root@localhost yunwei]# vim user.sh
#!/bin/bash
for user in xiaofang xiaowei jiumei alian
do
useradd $user
echo "$user 创建成功"
echo 1 | passwd --stdin $user &> /dev/null
echo "$user 密码设置成功,初始密码为“1”"
done

[root@localhost yunwei]# chmod u+x user.sh
[root@localhost yunwei]# ./user.sh
useradd:用户“xiaofang”已存在
xiaofang 创建成功
xiaofang 密码设置成功,初始密码为“1”
xiaowei 创建成功
xiaowei 密码设置成功,初始密码为“1”
jiumei 创建成功
jiumei 密码设置成功,初始密码为“1”
alian 创建成功
alian 密码设置成功,初始密码为“1”

#测试企业的服务器联通性
#!/bin/bash
for i in `seq 254`
do
ping -c2 -i0.1 -W1 192.168.0.$i &> /dev/null
if [ $? -eq 0 ];then
echo "192.168.0.$i UP"
else
echo "192.168.0.$i DOWN"
fi
done

[root@localhost yunwei]# chmod u+x ping.sh
[root@localhost yunwei]# ./ping.sh

#问题:如何将ping的命令结果存储到文件当中,正确的输出结果与错误的输出结果分别单独存储
#!/bin/bash
for i in `seq 254`
do
ping -c2 -i0.1 -W1 192.168.0.$i >> /dev/null
if [ $? -eq 0 ];then
echo "192.168.0.$i UP" >> up.txt
else
echo "192.168.0.$i DOWN" >> down.txt
fi
done
```

#### while循环

- 死循环,只要条件成立就重复执行命令

```shell
#while循环语法结构
while 条件判断
do
执行的命令
done

#编写while循环脚本
[root@localhost yunwei]# vim while.sh
#!/bin/bash
a=1
while [ $a -le 5 ]
do
echo $a
done

[root@localhost yunwei]# chmod u+x while.sh

#指定循环的固定次数
[root@localhost yunwei]# vim while.sh
#!/bin/bash
a=1
while [ $a -le 5 ]
do
echo $a
let a++
sleep 0.1
done

#使用while循环编写猜数字脚本
[root@localhost yunwei]# vim while1.sh
#!/bin/bash
num=$[RANDOM%10]
while :
do
read -p "请输入0-10之间的数字:" num1
if [ $num -eq $num1 ];then
echo "恭喜你才对了,奖励一个绝世容颜哇塞女孩!"
exit #退出脚本
else
echo "请继续努力,离哇塞女孩还差一步了,加油!"
fi
done


#利用while循环监控网卡进出口流量
[root@localhost ~]# vim net_ens32.sh
#!/bin/bash
while :
do
clear #清屏
ifconfig ens32 | head -2 #显示网卡头两行信息
ifconfig ens32 | grep "RX p" #网卡入口流量
ifconfig ens32 | grep "TX p" #网卡出口流量
sleep 0.2 #休眠0.2秒
done


#使用while循环编写一个测试整个网段IP地址的联通性脚本
[root@localhost yunwei]# vim while_ping.sh
#!/bin/bash
i=1 #定义一个变量
while [ $i -le 254 ] #循环判断变量的值小于等于254
do
IP="192.168.0.$i" #定义一个变量
ping -c2 -i0.1 -W1 $IP &> /dev/null #输出结果不要
if [ $? -eq 0 ];then #判断上一条命令的结果,如果上一条命令的结果等于0
echo "$IP UP" #输出主机UP
else
echo "$IP DOWN" #输出主机DOWN
fi
let i++ #对变量的值自加1
done
```

#### shell函数

- 在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数(给一堆命令取一个别名)
- 函数可以使脚本中的代码更加简洁,增强易读性,提高脚本的执行效率

```shell
#函数定义格式1
function 函数名 {
执行的命令1
执行的命令2
...省略更多命令
}

#函数定义格式2
函数名() {
执行的命令1
执行的命令2
...省略更多命令
}

#定义函数
[root@localhost ~]# net_ens32() {
> ifconfig ens32 | head -2
> ifconfig ens32 | grep "RX p"
> ifconfig ens32 | grep "TX p"
> }

#调用函数
[root@localhost ~]# net_ens32
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255
RX packets 2337 bytes 178268 (174.0 KiB)
TX packets 2686 bytes 467232 (456.2 KiB)

#定义函数
[root@localhost ~]# myinfo() {
> hostname
> cat /etc/redhat-release
> uname -r
> free -h
> df -h /
> }

#调用函数
[root@localhost ~]# myinfo
localhost
CentOS Linux release 7.6.1810 (Core)
3.10.0-957.el7.x86_64
total used free shared buff/cache available
Mem: 972M 393M 193M 13M 385M 374M
Swap: 2.0G 0B 2.0G
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 56G 5.2G 51G 10% /

#fork炸弹
[root@localhost yunwei]# vim fork.sh
#!/bin/bash
.() {
.|. &
}
.

[root@localhost yunwei]# chmod u+x fork.sh
[root@localhost yunwei]# ./fork.sh
```

#### 脚本中断及退出

- break #结束整个循环
- continue #结束本次循环,进入下一次循环
- exit #退出脚本

```shell
#结束第三次循环,进入下一次循环
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && continue
echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh
1
2
4
5
Over


#结束整个循环
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && break
echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh
1
2
Over

#直接退出脚本
[root@localhost yunwei]# vim for1.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && exit
echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh
1
2
```

posted @ 2022-01-11 14:24  日光倾城-  阅读(101)  评论(0)    收藏  举报