第14章练习,shell脚本编程实例-1

Posted

tags:

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

更多内容请点击:

Linux学习从入门到打死也不放弃,完全笔记整理(持续更新,求收藏,求点赞~~~~) 

http://blog.51cto.com/13683480/2095439


1,编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

if [ -z "$1" ]; then
        echo no argument 
        exit 1

elif    id "$1" &> /dev/null ;then
        echo usre "$1" is already exisit 
        exit 2
elif    useradd "$1" &> /dev/null ;then
        echo "$!"abc | passwd --stdin "$1" &> /dev/null
        ID=$(id -u "$1")
        HD=$(getent passwd|grep "$1" |cut -d: -f6)
        echo -e "user ${1} is add.\nUID:${ID}\nPASSWORD:${1}abc\nHOMEDIR:${HD}"
        exit 0
else
        echo user name is  illegal
        exit 3
fi

执行结果:

 技术分享图片


2、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息

read -t 10 -p "please input you answer. yes or no? : " ANS
if [ -z "$ANS" ]; then
        echo "I can't here anything"
        exit 1
fi
case $ANS in
[yY]|[yY][eE][Ss])
        echo your answer is yes
        exit 0
        ;;
[nN]|[nN][oO])
        echo your answer is no
        exit 0
        ;;
*)
        echo  "I don't understand you"
        exit 1
esac

执行结果:

技术分享图片

  

3、 编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

if [ -z "$1" ]; then
        echo there must be a filename argument
        exit 1
elif    [ ! -e "$1" ]; then
        echo no such file
        exit 1
elif    [ -d "$1" ]; then
        echo directory file
        exit 0
elif    [ -L "$1" ]; then
        echo link file
        exit 0
elif    [ -f "$1" ]; then
        echo normal file
        exit 0
else
        echo other file
        exit 0

fi

执行结果:

技术分享图片


4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数 

[ -z "$1" ] && echo no argument && exit 1
if [[ "$1" =~ ^[0-9]+$ ]] ; then
        echo int number
        case $1 in
        *1|*3|*5|*7|*9)
                echo and its an Odd number
                exit 0
                ;;
        *2|*4|*6|*8|*0)
                echo and its an Even number
                exit 0
                ;;
        *)
                echo unkown error
                exit 1
                ;;
        esac
else
        echo not int number
        exit 1
fi

额外增加了判断奇数还是偶数的功能,不过不能判断负数

执行结果:

技术分享图片

        

5、用for循环,编写一个脚本统计一下 /dev/下每种文件类型的文件分别有多少个,将结果打印出来。

declare -i cf=0
declare -i bf=0
declare -i df=0
declare -i lf=0
declare -i sf=0
declare -i pf=0
declare -i ff=0
declare -i of=0

[ -d "$1" ] || { echo putin a dir be argument;exit 1; }

for i in $1/* ;do

#for j in $(ls $1);do
#declare i=/dev/$j
        if   [ -c "$i" ];then
                #echo $i is en character file
                let cf++
        elif [ -b "$i" ];then
                #echo $i is a block file
                let bf++
        elif [ -d "$i" ];then 
                #echo $i is a directory file
                let df++
        elif [ -L "$i" ];then
                #echo $i is a link file
                let lf++
        elif [ -s "$i" ];then
                #echo $i is a socket file
                let sf++
        elif [ -p "$i" ];then
                #echo $i is a piping file
                let pf++
        elif [ -f "$i" ];then
                #echo $i is a numal file
                let ff++
        else
                #echo $i is other file
                let of++
        fi
done

let total=cf+bf+df+lf+sf+pf+ff+of
echo -e "tomal file number:\t $total "
echo -e "character file number:\t $cf "
echo -e "block file number:\t $bf "
echo -e "dir file number:\t $df "
echo -e "link file number:\t $lf "
echo -e "socket file number:\t $sf"
echo -e "piping file number:\t $pf"
echo -e "nomal file number:\t $ff"
echo -e "other file number:\t $of"

支持参数传递要查询的目录,不指定/var

执行结果:

技术分享图片


6、添加10个用户user1-user10,密码为8位随机字符

for i in user{1..10};do
        if id $i &>/dev/null;then
                echo $i is exist
        else 
                useradd $i &>/dev/null
                pass=$(openssl rand -base64 20|tr -dc [[:alpha:]]|cut -c1-8)
                echo $pass |passwd --stdin "$i" &>/dev/null
                echo user $i is add,password is: $pass
        fi
done

执行结果:

技术分享图片

附带删除脚本:

for i in user{1..10};do
        userdel -r $i &>/dev/null
        echo user $i is del
done

执行结果:

技术分享图片


7、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件, 以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop S66filename start

for i in `ls /etc/rc.d/rc3.d`;do
        if [[ "$i" =~ ^K.* ]];then
                echo -e "$i \t\tstop"
        elif [[ "$i" =~ ^S.* ]]; then
                echo -e "$i \t\tstart"
        else
                echo -d "$i \t\tother"
        fi
done

执行结果,centos6上效果明显一点,太晚了不想再开机了。。

技术分享图片


8、编写脚本,提示输入正整数n的值,计算1+2+…+n的总和

[[ "$1" =~ ^[0-9]+$ ]] || { echo no number; exit 1; }
bite=$(echo $1 |grep -o [0-9]|wc -l)
if [ $bite -gt 6 ];then
        echo too big number 
        exit 1
fi
declare -i sum=0
for i in $(seq 1 $1);do
        let sum=sum+i
done
echo sum=$sum
unset sum

执行结果:

技术分享图片


9、计算100以内所有能被3整除的整数之和

declare -i sum=0
declare -i i=1
while [ "$i" -le 100 ];do
        let sum+=i
        let i+=2
done
echo sum=$sum

执行结果:

技术分享图片


10、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态、

while true; do
        read -t 60 -p "input the network number: " netnum
        if [[ $netnum =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}0$ ]];then
                break
        else
                echo wrong network number
        fi  
done

last=$(echo $netnum|cut -d'.' -f3)
declare -i up=0
declare -i down=0

if [ $last != 0 ];then
        net=$(echo $netnum|cut -d'.' -f1-3)
        for i in {1..255};do
                j=${net}.$i
                { if ping -c1 -w1 $j &>/dev/null;then
                        echo host $j is up
                        let up++
                else 
                        #echo host $j is down
                        let down++
                fi; } & 

        done
        wait
        #echo
        #echo -e "uphost number is:\t $up"
        #echo -e "downhost number is:\t $down"

else 
        second=$(echo $netnum |cut -d'.' -f2)
        if [ $second = 0 ];then
                echo I cant do this. Its a too much big network
                exit 2
        else        
                net=$(echo $netnum |cut -d'.' -f1-2)
                for i in `seq 0 255`;do
                        j=${net}.$i
                        for k in `seq 0 255`;do
                                { h=${j}.$k
                                if ping -c1 -w1 $h &>/dev/null;then
                                        echo host $h is up
                                        let up++
                                else
                                        #echo host $h is dowm
                                        let down++
                                fi; } & 
                        done
                        wait
                done
                #echo 
                #echo -e "uphost number is:\t $up"
                #echo -e "downhost number is:\t $down"
        fi
fi

使用了并行执行,增加了测试效率,但是无法统计total,如需要统计totol 或者顺序显示,去掉并行执行,开启计数即可

执行结果:

技术分享图片


11、打印九九乘法表

for i in {1..9};do
        for j in `seq $i`;do
                let h=j*i
                echo -e "${j}x${i}=${h}\t\c"
        done
        echo
done

执行结果:使用while或者until循环都可以,就不单独演示了

技术分享图片


12、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html

for i in {1..10};do
        kk=$(openssl rand -base64 20|tr -dc [[:alpha:]]|cut -c1-8)
        touch /data/testdir/"$i""$kk".html 
done

执行结果:

技术分享图片


13、打印等腰三角形

while true;do
        read -t 30 -p "input the base length 2-50: " high
        if [[ "$high" =~ ^[1-9]?[0-9]$ ]] && [ "$high" -ge 2 -a "$high" -lt 51 ];then
                break
        else 
                echo wrong number
        fi
done

declare color

for i in `seq $high`;do
        let space=high-i
        let prin=2*i-1
        for j in `seq $space`;do
                echo -e " \c"
        done
        for k in `seq $prin`;do
                echo -e "\033[1;$[$RANDOM%7+31]m*\c"
        done
        for l in `seq $space`;do
                echo -e " \c"
        done
        echo
done

执行结果:增加了颜色显示

技术分享图片


14、编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大值和最小值

while true;do
        read -t 30 -p "input the base length 2-50: " high
        if [[ "$high" =~ ^[1-9]?[0-9]$ ]] && [ "$high" -ge 2 -a "$high" -lt 51 ];then
                break
        else 
                echo wrong number
        fi
done

declare color

for i in `seq $high`;do
        let space=high-i
        let prin=2*i-1
        for j in `seq $space`;do
                echo -e " \c"
        done
        for k in `seq $prin`;do
                echo -e "\033[1;$[$RANDOM%7+31]m*\c"
        done
        for l in `seq $space`;do
                echo -e " \c"
        done
        echo
done

执行结果:

技术分享图片

也可以基于数组实现:

declare -i max
declare -i min
for ((i=0;i<=9;i++));do
         num[$i]=$RANDOM
         if [ $i = 0 ];then
                let max=${num[$i]}
                let min=${num[$i]}
        else
                if [ ${num[$i]} -gt $max ];then
                        let max=${num[$i]}
                elif [ ${num[$i]} -lt $min ];then
                        let min=${num[$i]}
                fi
        fi
done
echo ${num[@]}
echo the max number is: $max
echo the min number is: $min

执行结果:

技术分享图片


15、编写脚本,实现打印国际象棋棋盘

### level=1
i=1
while [ $i -le 4 ];do
        j=1;k=1
        while [ $j -le 4 ];do
                echo -e "\033[49m  \033[0m\033[47m  \033[0m\c"
                let j++ 
        done
        echo
        while [ $k -le 4 ];do
                echo -e "\033[47m  \033[0m\033[49m  \033[0m\c"
                let k++ 
        done
        echo
        let i++ 
done
###
echo
echo this is level 1
echo
echo
#### level=2
#
declare -i s
while true;do
        read -p "choose the level 1-9: " s
                if [[ "$s" =~ ^[1-9]$ ]] &>/dev/null ;then
                        break
                else
                        echo wrong number
                fi
done

PS3="choose the first color(1-8): " 
select manu in red green yellow blue voilet light-blue white black;do
        case $manu in
        red)
                echo you have choose the $manu be the first color 
                break
                ;;
        green)
                echo you have choose the $manu be the first color
                break
                ;;
        yellow)
                echo you have choose the $manu be the first color 
                break
                ;;
        blue)
                echo you have choose the $manu be the first color 
                break
                ;;                                          
        voilet)
                echo you have choose the $manu be the first color 
                break
                ;;
        light-blue)
                echo you have choose the $manu be the first color
                break
                ;;
        white)
                echo you have choose the $manu be the first color 
                break
                ;;
        black)
                echo you have choose the $manu be the first color 
                break
                ;;
        *)
                echo i cant hera you
        esac    
done
first=$REPLY

PS3="choose the second color(1-8): " 
select manu in red green yellow blue voilet light-blue white black;do
        case $manu in
        red)
                echo you have choose the $manu be the second color 
                break
                ;;
        green)
                echo you have choose the $manu be the second color
                break
                ;;
        yellow)
                echo you have choose the $manu be the second color
                break
                ;;
        blue)
                echo you have choose the $manu be the second color
                break
                ;;
        voilet)
                echo you have choose the $manu be the second color
                break
                ;;
        light-blue)
                echo you have choose the $manu be the second color
                break
                ;;
        white)
                echo you have choose the $manu be the second color
                break
                ;;    
        black)
                echo you have choose the $manu be the second color
                break
                ;;
        *)
                echo i cant hera you
        esac    
done
second=$REPLY

let color1=40+first
let color2=40+second

#### while code

i=1
while [ $i -le 4 ];do
        j=1;while [ $j -le $s ];do
        
                k=1;while [ $k -le 4 ];do
                        m=1;n=1
                        while [ $m -le $s ];do
                                echo -e "\033[${color1}m  \033[0m\c"
                                let m++
                        done
                        while [ $n -le $s ];do
                                echo -e "\033[${color2}m  \033[0m\c"
                                let n++
                        done
                        let k++
                done
                echo
                let j++
        done
        j=1;while [ $j -le $s ];do
                k=1;while [ $k -le 4 ];do
                        m=1;n=1
                        while [ $m -le $s ];do
                                echo -e "\033[${color2}m  \033[0m\c"
                                let m++
                        done
                        while [ $n -le $s ];do
                                echo -e "\033[${color1}m  \033[0m\c"
                                let n++
                        done
                        let k++
                done
                echo
                let j++
        done
        let i++
done       

##ending

生成了2次菜单,可以考虑函数复用

执行结果:

        技术分享图片


16、后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机
        执行命令:  echo $RANDOM|md5sum|cut –c1-10  后的结果,请破解字符串对应的RANDOM值

i=1;while [ $# != 0 ];do
        j=1;while true ;do
                num=$(echo $j |md5sum |cut -c1-10)
                if [ $num = $1 ];then
                        break
                else
                        let j++
                fi
        done
        echo $1:$j
        shift
done

执行结果:参数还是需要手工输入,如过多,可以考虑写入文件之后使用while循环读取

技术分享图片

        

17、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并退出脚本

if [ -z $1 ];then
        echo no argument
        exit 1
else
        if id $1 &> /dev/null ;then
                if who |grep $1 &>/dev/null;then
                        echo user $1 is already running
                        exit 3
                fi
        else 
                echo no such user 
                exit 2
        fi
fi

while true;do
        sleep 3
        if who |grep $1 &>/dev/null;then
                echo "`date +%F-%T`: user $1 is login ">> /var/log/login.log
                exit
        fi
done

执行结果:

执行命令

技术分享图片

登录hello账号:

技术分享图片

发现命令已终止,查看日志已记录登录

技术分享图片

        

18、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出

declare num=$[$RANDOM%191+9]
declare -i time=0
while true ;do
        read -p "input a number 9-199: " ans
                let time+=1
                if [[ ! $ans =~ ^[0-9]+$ ]];then
                        continue
                elif [ $ans -gt $num ];then
                        echo  too big
                elif [ $ans -lt $num ];then
                        echo too small
                else
                        break
                fi
        if [ $time -ge 10 ];then
                echo times out,the right number is $num
                exit 1
        fi
done
echo binngo,the right number is $num

执行结果:

技术分享图片

执行结果2

技术分享图片


19、用文件名做为参数,统计所有参数文件的总行数

declare -i sum=0
until [ $# = 0 ];do
        if [ -f $1 ];then
                let sum+=$(cat $1|wc -l)
        else
                echo $1 is not found or wrong type file
        fi
        shift
done
echo
echo the totalline is : $sum

执行结果

技术分享图片


20、用二个以上的数字为参数,显示其中的最大值和最小值

if [ $# -lt 2 ];then
        echo at least 2 argument
        exit 1
fi

declare -i big
declare -i small
declare -i fir=$#
until [ $# = 0 ];do
        if [[ ! "$1" =~ ^[0-9]+$ ]];then 
                echo wrong number $1
                exit
        fi
        if [ $fir = $# ];then
                let big=$1
                let small=$1
        else 
                if [ $1 -gt $big ];then
                        let big=$1
                elif [ $1 -lt $small ];then
                        let small=$1
                fi
        fi
        shift
done
echo the biggest number is : $big
echo the smallest unmber is: $small

执行结果:

技术分享图片


21、编写脚本,实现2进制数与10进制数的转换

if [ "$1" = 2 -o "$1" = 10 ] && [[ "$2" =~ ^[0-9]+$ ]];then
        :
        else
                echo wrong argument
                exit 1
fi

if [ "$1" = 10 ]; then
##check the $2 is or not too big
        bite=$(echo "$2"|grep -o '[0-9]'|wc -l)
        if [ "$bite" -gt 19 ];then
                echo too big number "$2"
                exit 2
        fi
##Computing unit code
        declare -i x="$2"
        declare y
        while [ "$x" -gt 1 ];do
                gem=$[$x%2]
                x=$[x/2]
                y=$gem$y
        done
        y=$x$y
        echo $y
fi
##ending 1

if [ "$1" = 2 ];then
##check the $2 is or not too big
        bite=$(echo "$2"|grep -o '[0-9]'|wc -l)
        if [ "$bite" -gt 63 ];then
                echo too big number "$2"
                exit 2
        fi
##Computing unit code
##include judge the  $2 is or not a Binary number
        y=0
        let x=$bite-1                           
        b=$x
        for i in $(seq "$b") ;do
                j=$(echo "$2"|cut -c $i)
                if [ $j -gt 1 ];then
                        echo "$2" is not a Binary number.
                        exit 3
                else
                        y=$[j*2**x+y]
                        let x--
                fi
        done
        last=$(echo "$2"|cut -c "$bite")
        if [ "$last" -gt 1 ];then
                echo "$2"  is not a Binary number.
                exit 3
        else
                let y=y+last
                echo $y
        fi
fi      
##ending 2

补充说明:给定2个参数,参数1为“2”则表示参数2需要为2进制数,需要转换成10进制

                如果参数1 为“10”则表示参数2为10进制数,需要转化成2进制

                实际测试,发现shell最大支持计算值为2^64次方,所以二级数超过64位以上提示报错

执行结果1

         技术分享图片

执行结果2

        技术分享图片




以上是关于第14章练习,shell脚本编程实例-1的主要内容,如果未能解决你的问题,请参考以下文章

第14章,Shell脚本编程进阶

全国计算机等级三级Linux应用与开发技术考试-第4章shell脚本编程基础--练习题

shell编程

全国计算机等级考试三级Linux应用与开发技术考试-习题汇总

SHELL小练习

实验shell编程