Shell 一个月时间让你从小白到实战【万字笔记建议收藏方便学习】

作者主页

目录

为什么要学习Shell?

shell变量概述

变量使用

变量定义方式

截取

查看变量

清除变量

变量嵌套

开启新shell 全局变量

系统环境变量

位置参数

预定义变量

shell变量赋值

if比较

for循环

脚本题

变量替换

shell变量运算

流程控制语句

单分支语句

双分支语句

多分支语句

文件比较

与或非格式

流程控制语句-整数比对

流程控制语句-字符对比

正则表达式

流程控制语句-正则比对

case语句

循环语句

批量创建用户

批量探测主机是否存活

随机点名

随机猜数

程序语句

函数与数组

为什么要学习Shell?

1、什么是Shell

Shell是一种用户使用的解释型程序,它是操作系统的一部分,派生自多种不同的系统。它是一种命令解释器,它可以读取用户的输入,解释该输入,并执行相应的命令。 Linux的Shell有很多种,如bash,csh,ksh等。当前常用的为bash

2、Shell 的特性

(1)交互式:用户可以通过Shell的界面实现与计算机的交互,以便用户和计算机之间的信息交换。

(2)自动化: Shell 可以将用户编写的一系列命令,保存为脚本,并在需要的时候自.动执行,以减少用户的工作量。

(3)扩展性: Shell 可以实现过滤和管道功能,可以与其他应用程序和编程语言结合使用,实现不同应用程序、不同编程语言之间的信息传递

#!/bin/bash     #shell脚本应以此开头
chmod +x test.sh    #新脚本完成后需要给予运行权限
#脚本运行方法
./test.sh           #用户身份执行
/sh/test.sh         #用户身份执行
sh test.sh          #管理员身份执行
source test.sh      #管理员身份执行
. test.sh           #管理员身份执行
shell变量概述

变量是shell传递数据的一种方法,即用一个固定的字符串去表示不固定的值,便于后期引用

变量使用
a=34        #将固定字符a表示为34
echo $a     #返回a
34          #返回的执行结果
name="zhangsan"             #定义变量
age=19                      #定义变量
score=90                    #定义变量
id=1                        #定义变量
info="ID:$id Name:$name Age:$age Score:$score"     #在变量中引用变量
eccho $info                             #返回info
ID:1 Name:zhangsan Age:19 Score:90      #返回结果
time=$(date +%F)                        #变量中套用命令
echo $time              #返回time
2023-07-25      #返回的执行结果
变量定义方式
  • 用户自定义变量:人为定义变量

  • 系统环境变量:系统操作环境相对自带的

  • 位置参数变量:向脚本传递参数的变量

  • 预定义变量:bash定义好的变量

  1. 变量名不能出现"-",有空格时需要用引号括起来

 var=“hello word”

2.引用变量,$+变量名或者${变量名}

id=1                        #定义变量
info="ID:$id"               #引用id变量
 ​
name=zhangsan               #定义name变量
echo "${name}_is"           #引用name变量时后缀加_is
zhangsan_is                 #返回结果
 ​
例:
id=1
name=zhangsan
age=19
score=90
student="ID:${id}姓名:${name}年龄:${age}成绩:${score}"
echo $student
ID:1姓名:zhangsan年龄:19成绩:90
截取
ifconfig ens33|head -2|tail -1|awk '{print $2}'   #截取ip
df -hT|head -7|tail -1|awk '{print $6}'         #截取硬盘使用百分比
used *100 / buff/cache                  #内存占比公式定义为变量时双嵌套
mem=$((used *100 / buff/cache))         #计算
查看变量
 set |grep ip
清除变量
unset ip

引用变量,双引号属于弱引用取变量的值,单引号属于强引用原封不动引用变量

echo "$var hello china"         #需要引用变量值
echo '$var hello china'             #只想引用变量名,不执行$特殊符号
echo "$var hello china \$SHELL"  #部分变量执行,部分变量不执行
变量嵌套
aa=$(rpm -e $(rpm -qa|grep java))      #将由里向外运行命令
开启新shell 全局变量
bash        #开启一个新的shell,之前设定的所有局部变量将清空
export ip=$(ifconfig ens33|head -2|tail -1|awk '{print $2}')
#变量前加export时变量变为全局变量可在多个shell中使用,不加时默认为局部变量
系统环境变量
echo $PATH          #PATH路径,系统命令查找路径
/usr/local/bin:/usr/local/sbin:/usr/bin:usr/sbin        #PATH返回结果
export PATH=${PATH}:/sh             #在PATH中添加路径(重启丢失)
echo "export PATH=${PATH}:/sh" >> /etc/profile      #永久追加路径
echo "宿主目录: $HOME"
echo "当前目录: $PWD"
echo "主机名: $HOSTNAME"
echo "客户端地址和端口: $SSH_CONNECTION"
位置参数
vim  variable.sh 
#!/bin/bash 
echo "当前shell脚本的文件名:$0"
echo "第1个shell脚本位置参数:$1"
echo "第2个shell脚本位置参数:$2"
echo "第3个shell脚本位置参数:$3"
echo "第10个shell脚本位置参数:${10}"

例:

vi test.sh
#!/bin/bash
echo $(($1 + $2))
#
./test.sh 34 56         #34即为$1 56即为$2
90      #返回的值
vi test.sh
#!/bin/bash
​echo $1
echo $2
echo $3
echo $4
echo $5
#
./test.sh 23 34 45
23      #返回的值
34      #返回的值
45      #返回的值
预定义变量
echo $*     #所有传递的位置参数:
echo $@     #所有传递的位置参数:
echo $#     #共传递的参数数量
echo $$     #当前程序运行的PID:
echo $?     #返回上一个命令执行的返回结果为0时代表上一个命令成功其他为错误

 vi test.sh
#!/bin/bash
 ​
echo $*
echo $@
#
./test.sh 2 34 535 54 35 345
2 34 535 54 35 345      #返回的值所有传递的位置参数
2 34 535 54 35 345      #返回的值所有传递的位置参数
vi test.sh
#!/bin/bash
 ​
echo $#
#
./test.sh 2 34 535 54 35 345
6       #返回的值总共传递的参数数量
vi test.sh
#!/bin/bash
 ​
echo $$
#
./test.sh
6667        #返回的值脚本本身pid
shell变量赋值

例:read -p 交互方式变量赋值

 vi test.sh
#!/bin/bash
 ​
read -p "请输入第一个值:" num1
read -p "请输入第二个值:" num2
 ​
sum=$((num1 + num2))
echo "$num1 + $num2 = $sum"
#执行以上脚本
./test.sh
请输入第一个值:4       #返回结果
请输入第二个值:8       #返回结果
4 + 8 = 12              #返回结果
 &>      #混合输出将覆盖原文件的信息,&>>将追加至源文件信息后
ping -w1 -c1 baidu.com &> file
cat file
PING baidu.com (110.242.68.66) 56(84) bytes of data.        #file文件信息
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=128 time=21.5 ms    #file文件信息
                                                                 #file文件信息
--- baidu.com ping statistics ---                               #file文件信息
1 packets transmitted, 1 received, 0% packet loss, time 0ms     #file文件信息
rtt min/avg/max/mdev = 21.571/21.571/21.571/0.000 ms            #file文件信息
 ​
 ​
ping -c1 -w1 www.baidu.com &> /dev/null         #/dev/null为系统自带垃圾箱,放此后会删除
echo $?                                         #返回上一个命令执行的返回结果 0                                             0为真其他为假
if比较

 -e 文件名 如果文件存在则为真

 -r 文件名 如果文件存在且可读则为真

 -w 文件名 如果文件存在且可写则为真  

-x 文件名 如果文件存在且可执行则为真  

-s 文件名 如果文件存在且至少有一个字符则为真  

-d 文件名 如果文件存在且为目录则为真

 -f 文件名 如果文件存在且为普通文件则为真

 -c 文件名 如果文件存在且为字符型特殊文件则为真

 -b 文件名 如果文件存在且为块特殊文件则为真

 = 等于则为真  

!= 不相等则为真  

-z 字符串 字符串的长度为零则为真  

-n 字符串 字符串的长度不为零则为真

 -eq 等于则为真

 -ne 不等于则为真  

-gt 大于则为真  

-ge 大于等于则为真

 -lt 小于则为真  

-le 小于等于则为真

 

vi read3.sh
#!/bin/bash
read -p "请输入需要检测的ip地址:"IP
     
ping -w1 -c1 ${IP} &> /dev/null     #-c指定包的数量,-w为等待时间秒为单位 &>:混合输出至                                                                  #/dev/null:系统自带垃圾箱
if [ $? -eq 0 ];then                        #if [];then  条件,then满足时返回
                                            #$? -eq 0    $?返回的值等于0
     echo "${IP} 可以通信"                   #满足$? -eq 0时返回
else                                        #不满足上面条件时
     echo "${IP} 无法通信"   
fi
for循环
 for 将要使用的变量名 in 一个数列

   do

        要做的事情

   done

#!/bin/bash
 ​
read -p "请输入网段:" IP
for i in {1..254}
do
ping -c 1 -w 1 ${IP}.${i} &> /dev/null
if [ $? -eq 0 ];then
    echo -e "\033[32m ${IP}.${i}可以通信 \033[0m"
else
    echo -e "\033[31m ${IP}.${i}无法通信 \033[0m"
fi
done
 
脚本题

在每月第一天备份并压缩/etc目录的所有内容,放到/backup,备份文件以时间戳命名。 (1) 备份目录在哪,/backup (2) 备份目标是谁,/etc (3) 命令,tar (4) 时间戳命名,$(date +%F)

变量替换
url="www.baidu.com"
echo $url
www.baidu.com       #返回的值
echo ${url#*.}
baidu.com           #返回的值
${变量#匹配规则}              #从头开始匹配,最短删除
${变量##匹配规则}             #从头开始匹配,最长删除
${变量%匹配规则}              #从尾开始匹配,最短删除
${变量%%匹配规则}             #从尾开始匹配,最长删除
${变量/旧字符串/新字符串}         #替换字符串,仅替换第一个
${变量//旧字符串/新字符串}        #替换字符串,替换全部

例1:从前往后删变量内容

Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url    #直接返回变量
echo ${Qh_url#*.}   #删除.分隔的第一个字段
echo ${Qh_url##*.}  #仅保留最后一个字段

例2:从后往前删变量内容

Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url
echo ${Qh_url%.*}   #删除最后一个字段
echo ${Qh_url%%.*}  #仅保留第一个字段

例3:变量内容替换

Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url
echo ${Qh_url/u/U}    #替换从左往右第一个
echo ${Qh_url//u/U}    #替换所有
shell变量运算

1.整数运算,expr、$(())、$[],不支持小数运算 

a+b 加 a-b 减 a*b 乘(expr计算时,用 \ *) a/b 除 a%b 余

例1:

#只能进行整数之间的运算
a=20
b=10
#运算方式
expr $a + $b 
echo $(( $a + $b )) 
echo $[ $a + $b ]

例2:递增和递减

#每运行一次对应的数值就加1
echo $((a++))
echo $((a--))
echo $((++b))
echo $((--b))
echo $((100*(1+100)/2))     求1到100之和

脚本题: 例:查看内存使用率,仅保留整数

#!/bin/bash
Mem_use=$(free -m |grep ^M |awk '{print $3/$2*100}')
if [ ${Mem_use%.*} -ge 80 ];then    # -ge 大于等于
    echo "memory is overfull: ${Mem_use%.*}%"
else
    echo "memory is OK: ${Mem_use%.*}%"
fi 

例:查看磁盘使用状态,使用率超出80%就报警 思路: 怎么查看磁盘 怎么提取使用率 整数判断

#!/bin/bash
Disk=$(df -h |grep /$ |awk '{print $(NF-1)}')   #NF代表列的数量
 ​
if [ ${Disk%\%} -ge 80 ];then
    echo "你的磁盘使用率过高:$Disk"
else 
    echo "你的磁盘使用率正常:$Disk"
fi 

流程控制语句

单分支语句
 if [ 满足条件 ];then
         执行代码
     fi
     
#!/bin/bash
if [ while 1>0 ];then    #如果1>0
    echo "ok"
fi
双分支语句
if [ 满足条件 ];then
     执行代码
else    #如果上面条件不满足
    执行另一条代码
fi
 
#!/bin/bash
 ​
if grep "$1" /etc/passwd;then
    echo "ok"
else
    echo "error"
fi 
 
多分支语句
if [ 满足条件1 ];then
         执行代码1
elif [ 满足条件2 ];then
         执行代码2
else    #如果以上条件都不满足
         执行最后代码
fi 
 例:
#!/bin/bash
read -p "请输入用户名:"  User
 ​
if grep $User /etc/passwd &> /dev/null;then
    echo "用户$User存在"
     
elif ls -d /home/$User &> /dev/null;then
    echo "用户$User不存在"
    echo "但是$User宿主目录存在"
     
else 
    echo "用户$User不存在"
    echo "$User宿主目录也不存在"
fi 
 ​
文件比较
     -e  文件或目录是否存在           [ -e file ]
     -s  文件存在且至少有一个字符则为真 [ -s file ]
     -d  目录是否存在                  [ -d file ]
     -f  文件是否存在                  [ -f file ]
     -r  文件存在且可读                 [ -r file ]
     -w  文件存在且可写                 [ -w file ]
     -x  文件存在且可执行                [ -x file ]
#!/bin/bash
if [ -e /etc/passwd ];then
    echo "/etc/passwd存在"
else    
    echo "/etc/passwd不存在"
fi
#判断/etc/passwd是否存在
与或非格式
 &&  #与    1 && 1 = 1   0 && ? = 0  两者同时满足
 ||  #或    1 || ? = 1  0 || 1 = 1        两者满足其一
 !   #非    取反   !真  = 假        反之则为真
流程控制语句-整数比对
-eq     #等于则为真      [ $? -eq 0 ]
-ne     #不等则为真      [ $? -ne 0 ]
-gt     #大于则为真      [ 1 -gt 2 ]
-lt     #小于则为真      [ 1 -lt 2 ]
-ge     #大于等于则为真    [ 1 -ge 2 ]
-le     #小于等于则为真    [ 1 -le 2 ]
 例1:监控nginx状态,nginx故障则停止keepalived服务
#!/bin/bash
killall  -0  nginx
if  [ $? -ne 0 ];then
    systemctl stop keepalived
fi
     
 例2:判断服务是否运行
#!/bin/bash
if [ $# -ne 1 ];then
     echo "请在运行代码后输入一个服务名称"
     exit
fi
 ​
systemctl status "$1" &> /dev/null
if  [ $? -eq 0 ];then
     echo "$1 服务正在运行"
else
     echo "$1 服务没有运行"
     systemctl restart $1
     echo "$1 服务已重新启动"
fi 
流程控制语句-字符对比
=           等于则为真               [ "$a" == "$b" ]
!=          不等则为真               [ ! "$b" == "$a" ]
-z          字符长度为零则为真       [ -z "$a" ]
-n          字符长度不为零则为真  [ -n "$a" ]
str1>str2   str1大于str2则为真       [ str1>str2 ]
str1<str2   str1小于str2则为真       [ str1<str2 ]

#!/bin/bash
 ​
read -p "请输入yes/no:" n
if [ ${n} = "yes" ];then
         echo "this is ok"
else
         echo "this is no"
fi
#!/bin/bash
 ​
read -p "请输入你的分数" fs
expr $fs + 1 &> /dev/null
if [ $? -ne 0 ];then
         echo "请输入一个数字"
         exit
fi
if [ $fs -ge 0 -a $fs -le 60 ];then
         echo "成绩不及格,请补考"
elif [ $fs -gt 60 -a $fs -le 80 ];then
         echo "成绩合格"
elif [ $fs -gt 80 -a $fs -le 100 ];then
         echo "成绩优秀,恭喜"
else
         echo "成绩应在0-100之间"
fi

正则表达式

 $   #匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
 ( ) #标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
 *   #匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
 +   #匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
 .   #匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
 ?   #匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
 \   #将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
 ^   #匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
 {   #标记限定符表达式的开始。要匹配 {,请使用 \{。
 |   #指明两项之间的一个选择。要匹配 |,请使用 \|。
 限定符:
 *   #匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。
 +   #匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
 ?   #匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do" 、 "does"、 "doxy" 中的 "do" 。? 等价于 {0,1}。
 {n}  #n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o。
 {n,} #n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。
 {n,m}   #m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。
 x|y #匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"
 [xyz]   #字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 
         #注意!在中括号里面包含 ^ 表示"排除"
 [^xyz]#负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。
 [a-z] #字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。
 \b  #匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
 \B  #匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
 \d  #匹配一个数字字符。等价于 [0-9]。
 \D  #匹配一个非数字字符。等价于 [^0-9]。
 \s  #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
 \S  #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
 \w  #匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。
 \W  #匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。

举例

 ^[a-z][0-9]$  #匹配以字母开头,以数字结尾
 ^[^0-9][0-9]$ #匹配以非数字开头,以数字结尾
 [^a-z] #除了小写字母以外的所有字符 
 [^\\\/\^] #除了(\)(/)(^)之外的所有字符 
 [^\"\'] #除了双引号(")和单引号(')之外的所有字符
 ^[a-zA-Z_]$ #所有的字母和下划线  _
 ^a$ #字母a
 ^a{4}$  #aaaa
 ^a{2,4}$    #aa,aaa或aaaa
 ^a{1,3}$    #a,aa或aaa
 ^a{2,}$ #包含多于两个a的字符串
 ^a{2,}  #如:aardvark和aaab,但apple不行
 a{2,}   #如:baad和aaa,但Nantucket不行
 ^[a-zA-Z0-9_]{1,}$      # 所有包含一个以上的字母、数字或下划线的字符串 
 ^[1-9][0-9]{0,}$        # 所有的正整数 
 ^\-{0,1}[0-9]{1,}$      # 所有的整数 
 ^[-]?[0-9]+\.?[0-9]+$   # 所有的浮点数

流程控制语句-正则比对

#判断当前用户是否r开头
[[ "$USER" =~ ^r ]] && echo $?
#判断num变量是否为多个数字
[[ $num =~ ^[0-9]+$ ]]&& echo "成立"||echo "不成立"

脚本创建用户

#!/bin/bash
 ​
read -p "请输入用户名前缀:" q
if [[ ! ${q} =~ ^[a-Z]+$ ]];then
         echo "前缀应为字母组合"
         quit
fi
read -p "请输入用户名后缀(应为数字):" w
if [[ ${w} =~ ^[0-9]+$ ]];then
         user=${q}${w}
         useradd $user
         echo "123456" | passwd --stdin ${user} &> /dev/null
         echo "您当前指定的用户名为${user},初始密码为123456"
fi

同时创建多个用户

seq 100     #生成100个序列
#!/bin/bash
read -p "请输入要创建的用户名" name
if [[ $name =~ ^[0-9]+$ ]];then
         echo "用户名必须是数字"
         exit
fi
read -p "请输入要创建的个数" num
if [[ $num =~ ^[^0-9]+$ ]];then
         echo "用户数量必须是数字"
         exit
fi
for i in $(seq $num)
do
         user=${name}${i}
         useradd ${user} &> /dev/null
         echo '123' |passwd -stdin ${user} &> /dev/null
done
echo "创建完成,初始密码为123"
read -p "请输入要删除的用户名" name
read -p "请输入数量" num
for i in $(seq ${num})
do
         user=${name}${i}
         userdel -r ${user} &> /dev/null
done
echo "删除完成"
 

case语句

主要用在对菜单的处理。比if更简单明了,if适合针对一个范围进行判断。case适合等值判断

cat << END
------选项菜单-------
1.----copy-----------
2.----mv-------------
3.----backup---------
---------------------
END
read -p "请输入您的选择" n
case ${n} in
1)
        echo "copy"
        ;;
2)
        echo "mv"
        ;;
3)
        echo "backup"
        ;;
*)
        echo "不在菜单内"
        ;;
esac

案例:服务启动停止脚本

 
#!/bin/bash
if [ $1 == "start" ];then
         rsync --daemon
         echo "rsync已启动"
elif [ $1 == "stop" ];then
         killall rsync
         echo "rsync已关闭"
else
         echo "请配合start|stop"
         exit
fi
#/var/run/   #程序pid日志文件存储目录
sed -i 's/# pid file/pid file/' /etc/rsyncd.conf    #启动rsync的pid配置文件
. /etc/init.d/functions
 ​
case $1 in
​
start)
         if [ ! -f /var/run/rsyncd.pid ];then
                 rsync --daemon
                 action "rsync running.." /bin/true
         else
                 action "rsync 已启动" /bin/false
         fi
         ;;
stop)
         killall rsync
         ;;
status)
         echo "状态"
         ;;
*)
         echo "不在选项内"
         ;;
esac
 

举例

case启停nginx

#!/bin/bash
. /etc/init.d/functions
case $1 in
start)
         if [ -f /var/run/nginx.pid ];then
                 action "nginx已在运行状态无法重复运行" /bin/false
         else
                 sudo systemctl start nginx
                 if [ $? -eq 0 ];then
                         action "nginx启动成功" /bin/true
                 else
                         action "nginx启动失败请检查原因" /bin/false
                 fi
         fi
         ;;
stop)
         if [ -f /var/run/nginx.pid ];then
                 sudo systemctl stop nginx
                 if [ $? -eq 0 ];then
                         action "nginx关闭成功" /bin/true
                 else
                         action "nginx关闭失败" /bin/false
                                         fi
         else
                 action "nginx并未在运行" /bin/false
         fi
         ;;
reload)
         if [ -f /var/run/nginx.pid ];then
                 sudo systemctl restart nginx
                 if [ $? -eq 0 ];then
                         action "nginx重启成功" /bin/true
                 else
                         action "nginx重启失败" /bin/false
                 fi
         else
                 action "nginx未在运行中,无法进行重启" /bin/false
         fi
         ;;
status)
         if [ -f /var/run/nginx.pid ];then
                 echo "nginx正处于运行状态"
         else
                 echo "nginx现在未在运行"
         fi
         ;;
*)
         echo "请输入start|stop|reload|status"
         ;;
esac

循环语句

#重新定义分隔符
IFS=
#累加
((i=1;i<=100;i++))  #i的初始值为1,当i小于等于一百,i做累加
#结构
for 变量名 in
do     
循环命令语句

done
read -p "请输入最大值" n
 ​
for i in $(seq ${n})
do
         echo ${i}
done
a=1
b=9
for i in {1..9}
do
         let a++
         let b--
         echo $a:$b
 ​
done

批量创建用户
echo $((RANDOM))    #生成随机数
echo $((RANDOM))|md5sum #无序乱码随机数
echo $((RANDOM))|md5sum|cut -c 2-10 #截取第二位到第十位
#!/bin/bash
if [! $UID -eq 0 ];then
         echo "非管理员无权访问"
         exit
fi
read -p "请输入用户前缀" name
read -p "请输入创建数量" num
echo "创建用户${name}1到${name}-${num}"
read -p "确认创建(y/n)" m
case $m in
y)
         for i in $(seq $num)
         do
                 user=${name}${i}
                 id ${user} &> /dev/null
                 if [ $? -eq 0 ];then
                         echo "${user}已存在"
                 else
                         useradd ${user}
                         pass=$(echo $((RANDOM))|md5sum|cut -c 2-10)
                         echo ${pass}|passwd --stdin ${user} $> /dev/null
                         echo "用户名:${user} 密码:${pass}" >> /sh/user.txt
                 fi
         done
         echo "用户已创建完成,信息存放在/sh/user.txt中"
         ;;
n)
         exit
         ;;
*)
         echo "请输入y或n"
         ;;
esac
批量探测主机是否存活
#!/bin/bash
for i in $(seq 10)
do
         ip=192.168.154.${i}
         ping -c 1 -w 1 ${ip} &> /dev/null
         if [ $? -eq 0 ];then
                 echo "${ip} 可到达"
         else
                 echo "${ip}无法到达"
         fi
         echo ${ip} >> /tmp/ip.txt
done
wait
echo "ping 测试结束,端口测试开始"
for i in $(cat /tmp/ip.txt)
do
         nmap ${i} |grep 22 &> /dev/null
         if [ $? -eq 0 ];then
                 echo "${i} 22端口正常"
         else
                 echo "${i} 22端口未检出"
         fi
done
echo "测试完成"
随机点名
#!/bin/bash
#随机数公式,得到1-n范围的随机数
#RANDOM%n+1 
#sed -n "1p" student.txt #打印student.txt中的第一行
num=$(wc -l /sh/student.txt|awk '{print $1}')
for i in $(seq ${num})
do
         n=$((RANDOM%${num}+1))
         sed -n "${n}p" student.txt
         sleep 1     #暂停一秒
done
s=$(sed -n "${n}p" student.txt)
echo -e "就是你了:\033[32m $s \033[0m"
随机猜数
while true #无限循环
continue    #继续上一次操作
break   #退出循环到done后
#!/bin/bash
i=0
num=$((RANDOM%100+1))
while true
do
         read -p "请猜一个1-100的数字" s
         if [[ $s =~ ^[^0-9]+$ ]];then
                 echo "输入错误,请输入1-100的纯数字"
                 continue
         fi
 ​
         if  [ $s -gt $num ];then
                 echo "你猜大了"
         elif [ $s -lt $num ];then
                 echo "你猜小了"
         else
                 echo "你真厉害,猜对了"
                 break
         fi
         let i++
done
         echo "你总共猜了$(( $i + 1 ))次"
程序语句
 exit    #退出程序
 break   #打断循环执行循环之后的代码
 continue    #重新开始循环

最后给大家带上函数简单应用以便大家自己去进行拓展

函数与数组

定义函数 命令的集合,用来完成特定的功能; 提前定义函数,在脚本中任意调用函数名。 使用函数使代码模块化,便于重复使用,增加可读性。

#!/bin/bash
#函数定义格式:
#函数名(){
#     shell命令
#}
#     
#或
# ​
#function 函数名 {
#     shell命令
#}
#定义menu函数内容
#menu(){
#定义菜单时,应贴着左侧写
#cat << END
#1.创建用户
#2.删除用户
#3.退出程序
#END
#}
#调用menu
#menu
menu(){
cat << END
1.创建用户
2.删除用户
3.退出程序
END
}
input(){
        while true
        do
                read -p "请输入用户前缀:" name
                if [[ $name =~ [0-9]+ ]];then
                        echo "前缀不能包含数字"
                        continue
                fi
                break
        done
        while true
        do
                read -p "请输入用户数量" num
                if [[ $num =~ ^[^0-9]+$ ]];then
                        echo "数量应为数字"
                        continue
                fi
                break
        done
}
function create {
input
        read -p "将创建${name}1~${name}${num} {y/n}" m
        case ${m} in
        y)
                for i in $(seq $num)
                do
                        user=${name}${i}
                        id ${user} &> /dev/null
                        if [ $? -eq 0 ];then
                                echo "用户:${user}已存在"
                        else
                        useradd ${user} &> /dev/null
                        pass=$(echo $((RANDOM))|md5sum|cut -c 2-10)
                        echo ${pass}|passwd --stdin ${user} &> /dev/null
                        echo "用户名:${user} 密码:${pass}" >> /tmp/user.txt
                        echo "${user}创建成功"
                         fi
                        sleep 1
                done
                ;;
        n)
                 ;;
        *)
                echo "输入无效应为 y|n"
                create
                ;;
        esac
}
while true
do
menu
read -p "请对菜单进行选择(1-3)" y
case $y in
1)
        create
        ;;
2)
         echo 删除用户
       ;;
3)
 ​
        ;;
*)
        echo "选择无效,请选择 1|2|3"
        ;;
esac
done

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值