标签:shell linux 脚本编程 shell脚本编程 shell脚本编程习题
更多内容请点击: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
标签:shell linux 脚本编程 shell脚本编程 shell脚本编程习题
原文地址:http://blog.51cto.com/13683480/2120937