shell 练习

Posted 段小宝 

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell 练习相关的知识,希望对你有一定的参考价值。

脚本中的文件路径最好用 绝对路径。


练习参考

1.1 检查文件是否存在与属性

1.检查用户家目录中的 test.sh 文件是否存在,并且检查是否有执行权限。

新建文件 vim checkFile.sh
chmod +x checkFile.sh

方法一:
[ -e test.sh ] && [ -x test.sh ]

方法二:
[ -e ~/test.sh ] && echo "存在" || echo "不存在"
[ -x ~/test.sh ] && echo "有执行权限" || echo "没有执行权限"

方法三:

#!/bin/bash

[ -e ~/test.sh ]

if [ $? -eq 0 ]
 then echo "文件存在"
   [ -x ~/test.sh ]
   if [ $? -eq 0 ]
     then echo "文件有可执行权限"
     else
      echo "文件没有执行权限"
   fi
 else
   echo "文件不存在"
fi

1.2 跑步比赛信息输入

2.提示用户输入100米赛跑的秒数,要求判断秒数大于0且小于等于10秒的进入选拔赛,大于10秒的都淘汰,如果输入其它字符则提示重新输入;进入选拔赛的成员再进一步判断男女性别,男生进男生组,女生进女生组,如果输入错误请提示错误

sh runmatch.sh

#!/bin/bash

read -p "请输入你100米赛跑秒数:" second

if [ ${second} -gt 0 -a ${second} -le 10 ];then
        echo "进入选拔赛"
        read -p "请输入性别男/女:" sex
        if [ $sex = "男" -o $sex = "men" ];then 
        	echo "男生组"
        elif [ $sex = "女" -o $sex = "women" ];then 
        	echo "女生组"
        else
	        echo "输入错误" 
        fi
elif [ ${second} -gt 10 ];then 
	echo "淘汰"
else
    echo "请重新输入"
fi

1.3 case 判断压缩格式

3.用case语句解压根据后缀名为 .tar.gz 或 .tar.bz2 的压缩包到 /opt 目录

先使用进行压缩,位置在家目录中
tar -zcvf testsh.tar.gz test.sh
tar -jcvf people.tar.bz2 peopleMes.sh

编写脚本文件 vim zxvfsh.sh

case $1 in
*.tar.gz)
        echo "解压gz格式的文件"
        tar -zxvf $1 -C /opt/
        ;;
*.tar.bz2)
        echo "解压bz2格式的文件"
        tar -jxvf $1 -C /opt/
        ;;
*)
        echo "压缩格式不对"
esac

验证:

sh zxvfsh.sh testsh.tar.gz
sh zxvfsh.sh people.tar.bz2

dao /opt/ 目录下查看解压结果

1.4 判断是否为整数

4.提示用户输入内容,使用if 语句判断输入的内容是否为整数。

利用shell中算术运算只能是整数的原理,
也可以用 let int++ 都行,
能运算 $? 0,不能运算 $? 就为1.

编写脚本文件

read -p "请输入一个数:" int

#expr $int + 1 > /dev/null  #不让它输出相加的结果
#或者

tem=`expr $int + 1`

if [ $? -eq 0 ]
        then echo "$int 是整数"
else
        echo "$int 不是整数"
fi

1.5 判断奇偶数

5.根据上一题再判断输入的内容是奇数还是偶数。

能 %2 等于0的 就是偶数

vim isInt.sh

read -p "请输入一个数:" int

#expr $int + 1 > /dev/null  #不让它输出相加的结果
#或者

tem=`expr $int + 1`

if [ $? -eq 0 ]
        then echo "$int 是整数"
        #num=$[$int%2]
        if [ $[$int % 2] -eq 0 ]
                then echo "是偶数"
        else
                echo "是奇数"
        fi
else
        echo "$int 不是整数"
fi

执行脚本文件验证 sh isInt.sh

1.6 ping主机状态

6.用 if 语句判断主机是否存活

vim pingif.sh

ping -c 4 -i 0.5 -w 2 $1 > /dev/null

if [ $? -eq 0 ]
        then echo "存活"
else
         echo "不存活"
fi

验证:
sh pingif.sh 127.0.0.1
sh pingif.sh 189.64.1.2


1.7 在 /etc/init.d/ 中创建 linux启动脚本

参考

7 . 实验题

  • 用case语句在/etc/init.d/目录中写一个firewalld脚本,并加入到系统服务管理中
  • 使能够使用 service firewalld start|stop|restart|status 来管理firewalld服务,
  • 要求如果命令选项不对,则提示 “用法: $0 {start|stop|status|restart}”。
提示:
加入服务管理用chkconfig命令
vim /etc/init.d/firewalld
#!/bin/bash
#chkconfig: 35 99 20
#description:firewalld Service Control Script

chkconfig: 35 表示在 level 3 和 level 5  的 运行级别(runlevel)下启动

操作:

touch /etc/init.d/firewalld
chmod +x firewalld
ll

vim firewalld
#!/bin/bash
#chkconfig: 35 99 20
#description: Firewalld Service Control Script
#date:2021-05-10

#echo $1
#echo $0

case "$1" in
start)
        echo "Starting firewawlld Server..."
        systemctl start firewalld
        ;;
stop)
        echo "Stopping firewawlld  Server..."
        systemctl stop firewalld
        ;;
restart)
        echo "Restarting firewawlld Server..."
        systemctl restart firewalld
        ;;
status)
        echo "Firewalld status is ..."
        systemctl status firewalld
        ;;
*)
        echo "用法: $0 {start|stop|restart|status}"
esac

#exit 0 

使用chkconfig 加入到系统服务管理中:

chkconfig --add firewalld
chkconfig firewalld on  #将firewalld 加入开机启动

添加成功后就可以执行:service firewalld start、stop、restart、status

验证:

执行 service firewalld stop 的话,最终传到 /etc/init.d/firewalld 文件的参数就是 stop 
$0 表示 /etc/init.d/firewalld
$1 表示 start、stop、restart、status

在这里插入图片描述
方法二:

也可以用 $0 stop、 $0 start 递归调用自己的服务。
在这里插入图片描述

在这里插入图片描述


init.d 介绍
1、init.d 目录中存放的是一系列系统服务的管理(启动与停止)脚本。
2、用service命令可执行init.d目录中相应服务的脚本。

例:执行命令“service resin start”,可启动/etc/init.d/resin脚本

3、/etc/init.d是指向/etc/rc.d/init.d的软连接

4、 chkconfig httpd on #将httpd加入开机启动

扩展:查看 firewalld 运行状态 firewall-cmd --state

扩展:nginx 制作启动脚本


set 调试脚本

当脚本文件较长时,可以使用 set 命令指定调试一段脚本。

#!/bin/bash
set -x //开启调试模式
read -p "请输入您的分数(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
then
echo "$GRADE 分!优秀"
set +x //关闭调试模式
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]
then
echo "$GRADE 分,合格"
else
echo "$GRADE 分?不合格"
fi

2.1 计算从1到100所有整数的和

for

#!/bin/bash

read -p "输入一个数,计算1到这个数的和:" num

sum=0

for ((i=1;i<=$num;i++))
do
        sum=$[$sum+$i]
done

echo ""
echo "1到$num的和:" $sum

while

read -p "输入一个数,计算1到这个数的和:" num
sum=0
i=1

while [ $i -le $num ]
do
        sum=$[$sum+$i]
        let i++
done

echo ""
echo "1到$num的和:" $sum

util

read -p "输入一个数,计算1到这个数的和:" num

sum=0
i=1

until [ $i -gt $num ]
do
        sum=$[$sum+$i]
        let i++
done

echo ""
echo "1到$num的和:" $sum

执行脚本输入 100 即可
在这里插入图片描述

2.2 计算从1到该数的和

2.提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和

#!/bin/bash
read -p "输入一个数,计算1到这个数的和:" num

if [ $num -gt 100 ];then
        echo "数值太大,请输入小于100的数"
        exit 0
fi


sum=0

for ((i=1;i<=$num;i++))
do
        sum=$[$sum+$i]
done

echo ""
echo "1到$num的和:" $sum

在这里插入图片描述

#拓展 -10+-9+...+1
sum=0
for ((i=1;i>=-10;i--))
do
 sum=$[$sum+$i]
done

2.3 求从1到100所有整数的偶数和、奇数和

j_sum=0
o_sum=0

for ((i=1;i<=100;i++))
do
        if [ $[$i%2] -eq 0 ];then
                #echo "$i是偶数"
                o_sum=$[$o_sum+$i]
        else
                #echo "$i是奇数"
                j_sum=$[$j_sum+$i]
        fi
done

echo ""
echo "1到100 奇数和:" $j_sum
echo "1到100 偶数和:" $o_sum

结果:
在这里插入图片描述

2.4 新增用户

4.执行脚本输入用户名,若该用户存在,输出提示该用户已存在;若该用户不存在,提示用户输入密码,建立用户并设立其密码

方法一(不推荐):

注:grep 需要使用 -w 选项进行整个单词精确查找;
只能使用passwd 文件中的第一列进行判断用户。

#!/bin/bash

#USERS=`cat ~/adduser.txt`
#echo "文件中的用户有:" $USERS

read -p "请输入需要新增的用户名:" USERS
echo ""
for u in $USERS
do
 if [ `cat /etc/passwd | awk -F ':' '{print $1}' | grep -w $u` ];then
        echo $u "用户已存在"
        echo ""
 else
 		echo "正在新增$u用户"
        useradd $u &> /dev/null
        read -p "请为用户$u设置密码:" psd
        echo $psd | passwd --stdin $u &> /dev/null
        echo "新增用户:$u 成功!"
        echo ""
 fi
done

验证,创建多个用户
在这里插入图片描述
在这里插入图片描述
方法二(推荐):

使用 id 用户名 获取用户信息,$? 获取状态, 0 表示有这个用户,非0没有这个用户
在这里插入图片描述

#!/bin/bash
read -p "请输入用户名:" USERS

for u in $USERS
do
        id $u&> /dev/null
        if [ $? -eq 0 ];then
                echo "$u用户已存在!"
        elif [ $? -ne 0 ];then
                read -p "正在创建$u,请输入密码:" pass
                useradd $u
                echo $pass | passwd --stdin $u &> /dev/null
                echo "创建用户$u成功!"
        fi 
done

2.5 循环检测主机

5.检测指定范围主机是否通信,并将通信的主机ip输出到文件 /opt/host_ip 中

注:我的本地IP网段是 192.168.31.0
创建的几台虚拟机IP是192.168.31.100+ ,我起了两台 100 和 101(本机),对 99 到 103 四台机器进行测试。

vim multip.sh

#!/bin/bash

for i in {99..103}
do
ping -c 1 -i 0.2 -w 1 192.168.31.$i &> /dev/null
   if [ $? -eq 0 ]
   then
        echo "与主机 192.168.31.$i 可以通信"
        echo "与主机 192.168.31.$i 可以通信" >> /opt/host_ip
   else
       echo "与主机 192.168.31.$i 不能通信"
   fi
done

验证
sh multip.sh
在这里插入图片描述

2.6 判断密码是否正确

6.用户输入密码,脚本判断密码是否正确,输入正确提示正确信息,连续输错3次则报警

用户名和密码以 test 123456 为例

#!/bin/bash

for i in {1..3}                       #最多执行3
do
    read -p "请输入用户名:" user
    read -p "请输入密码:" psd
    echo ""
    if [ "$user" == 'test' -a "$psd" == '123456' ];then #模拟正确用户密码
        echo "用户$user密码正确!登录成功!"
        exit 0   #直接退出shell,后面文件的内容都不执行
    else
        echo "密码错误,请重试!"
        echo ""
    fi
done

echo "警告!已经尝试三次!"

结果
在这里插入图片描述

2.7 随机生成8位密码

7.编写能够自动生成一个8位随机密码的脚本

方法一(没用循环):

#!/bin/bash
#获取uuid 前八位
psd="/proc/sys/kernel/random/uuid"
UUID=`echo $(cat $psd)`
echo ${UUID:0:8}

方法二:

使用 $RANDOM 随机生成不同的数字,然后再进行 md5sum 命令进行加密,这样就可以获取到不同的字符串了,再使用 cut -c 1 获取第一个字符,或 cut -c 1-8 直接获取。

#!/bin/bash

psd=""
for i in {1..8}
do
        s=`echo $RANDOM | md5sum | cut -c 1`
        psd=$psd$s
done
echo $psd

验证:
在这里插入图片描述
在这里插入图片描述

方法三:

Str="12345qweriuiotyuasjkfHGmnzxcbvm456874"
psd=""
for i in `seq 1 8`
do
  index=$[$RANDOM%${#Str}]
  num=${Str:$index:1}
  psd+=$num
done
echo $psd

2.8 淘宝购物

8.写个逛淘宝选购商品脚本,每家商店有五种商品选购(衣服500元,裤子400元,鞋子350元,帽子150元,袜子50元),每次选购完或不买都会提示用户是否继续逛下一家商店,如果不再继续逛的话进行购物车结算总额。

思路:写个死循环,在里面通过 continue 和 break 命令来判断是继续执行下一次循环体 还是直接结束循环。case 判断选择哪个商品,全局变量money保存总金额,每次选完后提示输入,根据输入值进行判断再执行一次循环还是退出。

#!/bin/bash

money=0

while(true)
do
 echo "------------------------"	
 echo "1:衣服¥500"
 echo "2:裤子¥400"
 echo "3:鞋子¥350"
 echo "4:帽子¥150"
 echo "5:袜子¥50"
 echo "其他:结算"
 echo "------------------------"
 echo ""

 read -p "请输入购买商品的序号:" name

 case $name in
  1)
	echo "衣服加购成功!"
	let money+=500
	;;
  2)
	echo "裤子加购成功!"
	let money+=400
	;;
  3)
	echo "鞋子加购成功!"
	let money+=350
	;;
  4)
	echo "帽子加购成功!"
	let money+=150
	;;
  5)
	echo "袜子加购成功!"
	let money+=50
	;;
  *)
	echo "再见,你本次消费计算金额为:¥$money"
	break;
 esac

 read -p "继续购物吗(y/n):" choice
 if [ $choice = "y" ];then
	continue;
 else
	echo "再见,你本次消费计算金额为:¥$money"
	break;
 fi
 
done

sh taobao,sh
在这里插入图片描述

3.1

以上是关于shell 练习的主要内容,如果未能解决你的问题,请参考以下文章

Shell练习小程序练习练习——九九乘法表

spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段

Python练习册 第 0013 题: 用 Python 写一个爬图片的程序,爬 这个链接里的日本妹子图片 :-),(http://tieba.baidu.com/p/2166231880)(代码片段

shell脚本练习题

shell脚本小练习

Shell练习获取彩票开奖结果