注:以下脚本练习实验都是以root用户身份执行的,若普通用户运行需要另加相应的权限

1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。

[root@fengl bin]# vim systeminfo.sh
[root@fengl bin]# chmod u+x systeminfo.sh
[root@fengl bin]# cat systeminfo.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小
HostName=`hostname`
IpAddr=`(ifconfig|grep Mask||ifconfig|grep netmask)|tr -s ' '|cut -d ' ' -f 3|grep -o '\<[[:digit:].]\+\>'|grep -v '127.0.0.1'|tr '\n' ' '`
Version=`cat /etc/centos-release`
Kernel=`uname -r`
CPU=` lscpu | grep "Model name"|tr -s ' '|cut -d: -f2`
Mem=`free -h|grep 'Mem'|tr -s ' '|cut -d: -f2|cut -d' ' -f2`
Disk=`fdisk -l|sed -n '2p'|cut -d: -f2`
echo -e "\033[31;1mHostName\033[0m:\033[32;1m$HostName\033[0m"
echo -e "\033[31;1mIPv4Addr\033[0m:\033[32;1m$IpAddr\033[0m"
echo -e "\033[31;1mOS Version\033[0m:\033[32;1m$Version\033[0m"
echo -e "\033[31;1mKernel\033[0m:\033[32;1m$Kernel\033[0m"
echo -e "\033[31;1mCPU model name\033[0m:\033[32;1m$CPU\033[0m"
echo -e "\033[31;1mMemory\033[0m:\033[32;1m$Mem\033[0m"
echo -e "\033[31;1mDisk\033[0m:\033[32;1m$Disk\033[0m"

bash脚本练习_第1张图片

2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

[root@fengl bin]# vim backup.sh
[root@fengl bin]# chmod u+x backup.sh 
[root@fengl bin]# cat backup.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:每日将/etc/目录备份到/root/etcYYYY-mm-dd中
BackDir="/root/etc`date +%F`"
SourceDir="/etc"
echo "正在备份/etc目录下的文件,请等待..."
cp -a "${SourceDir}"/. "${BackDir}"
SFile="/root/.sfile`date +%F`"
BackFile="/root/.backfile`date +%F`"
echo "正在检测备份文件,请等待..."
[[ -d "${BackDir}" ]] && ls -aR ${BackDir} > ${BackFile} && sed -i 's@'${BackDir}'@/etc@g' "${BackFile}" && ls -aR ${SourceDir} > ${SFile} && [[ "`cat ${BackFile}`" == "`cat ${SFile}`" ]] && echo "备份成功" || echo -e "\033[31;1m备份失败,请重新备份\033[0m" && rm -f {${SFile},${BackFile}}

注:脚本中验证备份文件功能只是为了练习,实际上没有多大意义

bash脚本练习_第2张图片

bash脚本练习_第3张图片

3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值及分区

[root@fengl bin]# vim disk.sh
[root@fengl bin]# chmod u+x disk.sh 
[root@fengl bin]# cat disk.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:显示当前硬盘分区中空间利用率最大的值及分区
MaxNum=`df|grep "^/dev/sd"|tr -s ' '|cut -d' ' -f5|tr -d '%'|sort -nr|head -1`
Partition=`df|tr -s ' '|cut -d' ' -f1,5|grep "${MaxNum}"|cut -d' ' -f1|tr '\n' ' '`
echo -e "\033[31;1m当前硬盘分区中空间利用率最大值为\033[0m:\033[32;1m${MaxNum}%\033[0m"
echo -e "\033[31;1m当前硬盘分区中空间利用率最大的分区为\033[0m:\033[32;1m${Partition}\033[0m"

wKiom1ewIU2Sz1wTAAAoKQ4przk188.png

4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序

[root@fengl bin]# vim links.sh
[root@fengl bin]# chmod u+x links.sh
[root@fengl bin]# cat links.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:显示连接当前主机的每个远程主机IPv4地址及连接数,并按连接数从大到小排序
echo -e "\t连接数\t远程主机"
netstat -nt|grep 'tcp'|tr -s ' '|cut -d' ' -f5|cut -d: -f1|uniq -c|tr -s ' '|sort -nr|tr ' ' '\t'

wKioL1ewIWDBlfI_AAASMG6910U178.png

5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

[root@fengl bin]# vim sumid.sh
[root@fengl bin]# chmod u+x sumid.sh
[root@fengl bin]# cat sumid.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:计算/etc/passwd文件中的第10个用户和第20用户的ID之和
Uid10th=` sed -n '10p' /etc/passwd|cut -d: -f3`
Uid20th=` sed -n '20p' /etc/passwd|cut -d: -f3`
SumUid=$[Uid10th+Uid20th]
echo -e "/etc/passwd文件中的第10个用户和第20个用户的ID之和为:\033[32;1m$SumUid\033[0m"

wKiom1ewIXSDWKTgAAAYZX-wc9o199.png

6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

[root@fengl bin]# vim sumspace.sh 
[root@fengl bin]# chmod u+x sumspace.sh
[root@fengl bin]# cat sumspace.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:传递两个文件路径作为参数给脚本,计算出两个文件中所有空白行之和

#判断是否输入两个参数,否则退出并提示
[[  "$#" -ge 2 ]] || echo -e "\033[31;1m请输入两个文件路径作为参数\033[0m"
[[  "$#" -ge 2 ]] || exit
#判断参数1是否为文件路径,否则退出并提示
[[ -f "$1" ]] || echo -e "\033[31;1m第一个输入的文件路径${1}不存在,请重新输入一个正确的文件路径作为参数\033[0m"
[[ -f "$1" ]] || exit
#判断参数2是否为文件路径,否则退出并提示
[[ -f "$2" ]] || echo -e "\033[31;1m第二个输入的文件路径${2}不存在,请重新输入一个正确的文件路径作为参数\033[0m"
[[ -f "$2" ]] || exit
#分别定义两个变量记录文件1和文件2中空白行的个数
File1Num=`grep '^$' $1| wc -l`
File2Num=`grep '^$' $2| wc -l`
#计算文件1和文件2中空白行个数之和
let Sum=${File1Num}+${File2Num}
#输出文件1和文件2中空白行个数之和
echo -e "\033[33;1m$1和$2中所用空白行之和为\033[0m:\033[32;1m${Sum}\033[0m"

bash脚本练习_第4张图片

7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

[root@fengl bin]# vim sumfile.sh
[root@fengl bin]# chmod u+x sumfile.sh
[root@fengl bin]# cat sumfile.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:统计/etc, /var, /usr目录中共有多少个一级子目录和文件
EtcNum=`ls -A /etc/|wc -l`
VarNum=`ls -A /var/|wc -l`
UsrNum=`ls -A /usr/|wc -l`
Sum=$((EtcNum+VarNum+UsrNum))
echo -e "\033[31;1m/etc,/var,/usr目录中的一级子目录和文件共有\033[0m:\033[32;1m${Sum}\033[0m"

wKiom1ewIaXB_OuzAAAYPDCNA9I355.png

8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

[root@fengl bin]# vim argsnum.sh
[root@fengl bin]# chmod u+x argsnum.sh
[root@liang7 bin]# cat argsnum.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:统计第一个参数路径文件的空白行数

#判断是否输入参数,否则提示并退出
[[ $# -lt 1 ]] && echo -e "\033[31;1m请至少输入一个文件路径作为参数\033[0m" && exit
#判断输入的是否文件路径,否则提示并退出
[[  -f $1  ]] || echo -e "\033[31;1m输入的文件路径不存在,请在argsnum.sh后面重新输入一个正确的文件路径作为参数\033[0m" 
[[  -f $1  ]] || exit
#计算第一个参数文件中空白行数
FileSpaceLineNum=`grep '^$' $1|wc -l`
#输出第一个参数文件中空白行数
echo -e "\033[31;1m第一个参数文件中的空白行数为\033[0m:\033[32;1m${FileSpaceLineNum}\033[0m"

bash脚本练习_第5张图片

9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

[root@fengl bin]# vim hostping.sh
[root@fengl bin]# chmod u+x hostping.sh
[root@fengl bin]# cat hostping.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:输入一个IPv4地址作为参数,测试是否能够ping通并提示

#判断有无参数,若无参数则提示并退出
[[ -z $@ ]] && echo -e "\033[31;1m请输入一个IPv4地址作为参数\033[0m" && exit
#判断是否只有一个参数,如果有多个参数则提示并退出
[[ $# -gt 1 ]] && echo -e "\033[31;1m只能输入一个参数作为IPv4地址\033[0m" && exit
#判断参数是否为有效的IPv4地址,若不是则提示并退出
echo "$1"|grep -E '^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' &> /dev/null || echo -e "\033[31;1m请输入一个正确的IPv4地址\033[0m"
echo "$1"|grep -E '^([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' &> /dev/null || exit
#ping该IPv4地址,并反馈结果
echo -e "\033[31;1m正在 ping "$1",请等待...\033[0m"
ping -c2 -W2 "$1" &> /dev/null && echo -e "\033[32;1m主机"$1"可访问\033[0m" || echo -e "\033[31;1m主机"$1"不可访问\033[0m"

bash脚本练习_第6张图片

10、chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件是否不可读且不可写(因考虑到普通用户调用该脚本权限问题,故将脚本路径放到了/tmp/目录下,并且该脚本还可以判该文件的其他权限)

[root@fengl tmp]# vim per.sh 
[root@fengl tmp]# chmod 745 per.sh
[root@fengl tmp]# cat per.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:判断当前用户对某文件的读、写、执行权限并提示

#定义要检测文件的路径变量并赋值
SourceFile=/tmp/file1
#定义要检测文件的权限变量并赋值
[[ -r "${SourceFile}" ]]
Read=`echo $?`
[[ -w "${SourceFile}" ]]
Write=`echo $?`
[[ -x "${SourceFile}" ]]
Execute=`echo $?`
#检测当前用户对该文件的读、写、执行权限
[[ "${Read}" -eq 0 ]] && [[ "${Write}" -eq 0 ]] && [[ "${Execute}" -eq 0 ]] && echo -e "\033[32;1m当前用户对${SourceFile}文件有读、写、执行权限\033[0m"
#检测当前用户对该文件的读、写权限
[[ "${Read}" -eq 0 ]] && [[ "${Write}" -eq 0 ]] && [[ "${Execute}" -gt 0 ]] && echo -e "\033[34;1m当前用户对${SourceFile}文件有读、写权限\033[0m"
#检测当前用户对该文件的读、执行权限
[[ "${Read}" -eq 0 ]] && [[ "${Write}" -gt 0 ]] && [[ "${Execute}" -eq 0 ]] && echo -e "\033[34;1m当前用户对${SourceFile}文件有读、执行权限\033[0m"
#检测当前用户对该文件的写、执行权限
[[ "${Read}" -gt 0 ]] && [[ "${Write}" -eq 0 ]] && [[ "${Execute}" -eq 0 ]] && echo -e "\033[33;1m当前用户对${SourceFile}文件有写、执行权限\033[0m"
#检测当前用户对该文件的读权限
[[ "${Read}" -eq 0 ]] && [[ "${Write}" -gt 0 ]] && [[ "${Execute}" -gt 0 ]] && echo -e "\033[34;1m当前用户对${SourceFile}文件只有读权限\033[0m"
#检测当前用户对该文件的写权限
[[ "${Read}" -gt 0 ]] && [[ "${Write}" -eq 0 ]] && [[ "${Execute}" -gt 0 ]] && echo -e "\033[33;1m当前用户对${SourceFile}文件只有写权限\033[0m"
#检测当前用户对该文件的执行权限
[[ "${Read}" -gt 0 ]] && [[ "${Write}" -gt 0 ]] && [[ "${Execute}" -eq 0 ]] && echo -e "\033[33;1m当前用户对${SourceFile}文件只有执行权限\033[0m"
#检测当前用户对该文件无任何权限
[[ "${Read}" -gt 0 ]] && [[ "${Write}" -gt 0 ]] && [[ "${Execute}" -gt 0 ]] && echo -e "\033[31;1;5m当前用户对${SourceFile}文件无任何权限\033[0m"

下面图1是root用户更改file1权限的截图,图2是普通用户针对file1文件不同权限的测试结果截图

图1:

bash脚本练习_第7张图片

图2:

bash脚本练习_第8张图片

11、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统。

[root@fengl bin]# vim nologin.sh 
[root@fengl bin]# chmod u+x nologin.sh
[root@fengl bin]# cat nologin.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:禁止普通用户登录

#检测/etc目录下有无nologin文件,并定义回执变量
[[ -f /etc/nologin ]]
EtcReturnNum=`echo $?`
#检测/run目录下有无nologin文件,并定义回执变量
[[ -f /run/nologin ]]
RunReturnNum=`echo $?`
#禁止普通用户登录
[[ ${EtcReturnNum} -eq 0 ]] || [[ ${RunReturnNum} -eq 0 ]] && echo -e "\033[31;1m已禁止普通用户登录该系统\033[0m" && exit
[[ $"EtcReturnNum" -gt 0 ]] && [[ $"RunReturnNum" -gt 0 ]] && touch /etc/nologin && echo -e "\033[31;1m已禁止普通用户登录该系统\033[0m"

bash脚本练习_第9张图片

[root@fengl bin]# vim login.sh 
[root@fengl bin]# chmod u+x login.sh
[root@fengl bin]# cat login.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:允许普通用户登录

#检测/etc目录下有无nologin文件,并定义回执变量
[[ -f /etc/nologin ]]
EtcReturnNum=`echo $?`
#检测/run目录下有无nologin文件,并定义回执变量
[[ -f /run/nologin ]]
RunReturnNum=`echo $?`
#允许普通用户登录
[[ $"EtcReturnNum" -eq 0 ]] && rm -f /etc/nologin
[[ $"RunReturnNum" -eq 0 ]] && rm -f /run/nologin
echo -e "\033[32;1m已允许普通用户登录该系统\033[0m"

bash脚本练习_第10张图片

12、计算1+2+3+...+100的值

[root@fengl bin]# vim sum.sh
[root@fengl bin]# chmod u+x sum.sh
[root@fengl bin]# cat sum.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:计算1~10的和

#指定数字范围变量
Num=`echo {1..100}`
#计算求和
#方法一:
#let sum=`echo $Num | tr -t ' ' '+'`
#方法二:
#sum=$[`echo $Num | sed 's@[[:space:]]@+@g'`]
#方法三:
#sum=$((`seq 1 100 | tr -t '\n' '+'|sed 's@+$@@'`))
#方法四:
#sum=$(expr `seq 1 100|tr -t '\n' '+'|sed 's@+@ + @g'|sed 's@ + $@@'`)
#方法五:
sum=`echo $Num|tr -t ' ' '+'|bc`
echo -e "\033[32;1m1~100的和为\033[0m:\033[33;1m${sum}\033[0m"

wKiom1ewIpLidQMFAAAQyvEbwGs149.png

13、计算从脚本第一参数A开始,到第二个参数B的所有数字的总和,判断B是否大于A,否提示错误并退出,是则计算之

[root@fengl bin]# vim parametersum.sh 
[root@fengl bin]# chmod u+x parametersum.sh 
[root@fengl bin]# cat parametersum.sh 
#!/bin/bash
#Author:liang
#Version:1.0
#Description:计算该脚本第一个参数中所有数字和第二个参数中的所有数字之和,并判断第二个参数中所有数字之和是否大于第一个参数中所有数字之和,是则计算,否则提示错误并退出

#检测是否有参数
[[ $# -ge 2 ]] || echo -e "\033[31;1m请至少输入两个带有数字的参数\033[0m"
[[ $# -ge 2 ]] || exit
#检测参数知否有效
echo $1|grep '[0-9]\+' &> /dev/null || echo -e "\033[31;1m参数${1}无效,请重新输入\033[0m"
echo $1|grep '[0-9]\+' &> /dev/null || exit
echo $2|grep '[0-9]\+' &> /dev/null || echo -e "\033[31;1m参数${2}无效,请重新输入\033[0m"
echo $2|grep '[0-9]\+' &> /dev/null || exit
#分别取出第一个参数和第二个参数中的所有数字,并分别计算每个参数中的数字之和
NumA=`echo $1 | grep -o '[0-9]\+'|tr -d '\n'`
NumB=`echo $2 | grep -o '[0-9]\+'|tr -d '\n'`
SumA=$[`echo ${NumA} | sed 's@[0-9]@&+@g' | sed 's@+$@@'`]
SumB=$[`echo ${NumB} | sed 's@[0-9]@&+@g' | sed 's@+$@@'`]
#检测第二个参数中的数字之和是否大于第一个参数中的数字之和
[[ ${SumB} -gt ${SumA} ]] || echo -e "\033[31;1m第二个参数中数字之和小于或等于第一个参数中的数字之和,请重新输入\033[0m"
[[ ${SumB} -gt ${SumA} ]] || exit
#计算两个参数中的所有数字之和
SumAB=$[SumA+SumB]
echo -e "\033[33;1m两个参数中所有数字之和为\033[0m:\033[32;1m${SumAB}\033[0m"

bash脚本练习_第11张图片