shell脚本编程进阶

在linux shell中,通常我们将一些命令写在一个文件中就算是一个shell脚本了,但是如果需要执行更为复杂的逻辑判断,我们就需要使用流程控制语句来支持了。
所谓流程控制既是通过使用流程控制语句对程序流程的选择、循环、转向和返回等进行控制。流程控制是所有编程语言分重要组成部分,linux shell同样有一套自己的流程控制语句,其中主要包括条件语句(if),循环语(for,while),选择语句(case)。

条件选择if语句

单分支

if判断条件;then

      条件为真的分支代码

fi

双分支

if 判断条件; then 
   条件为真的分支代码 
else 
   条件为假的分支代码 
fi

多分支

if 判断条件1; then 
   条件为真的分支代码 
elif 判断条件2; then 
   条件为真的分支代码 
elif 判断条件3; then 
   条件为真的分支代码 
else 
   以上条件都为假的分支代码 
fi

逐个条件进行判断,第一次为“真”条件时,接着执行其分支,而后结束整个if语句

条件判断case语句

case 变量引用 in        #变量的引用加$
PAT1) 
    分支1 
    ;;
PAT2) 
    分支2 
    ;;
... 
\*) 
    默认分支 
    ;; 
esac

case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b

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

#!/bin/bash

read -p "please input username:" username
useradd $username &> /dev/null
if [ $? -eq 0 ];then
    echo "add $username user" && id $username
else
    echo "the user already exits"
fi

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

#!/bin/bash

read -p "Do you agree? yes or no: " ANS
if [ -z "$ANS" ] ;then
   echo "Please input yes or no"
   exit
fi
case $ANS in
[Yy]|[Yy][Ee][Ss])
   echo "Your answer is YES"
   ;;
[Nn]|[Nn][Oo])
   echo "Your answer is NO"
   ;;
*)
   echo "Your answer is fales"
esac

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

#!/bin/bash

read -p "input file or dir:" choose
[ -z "$choose" ] && echo "Please input a file or dir"
if [ -d "$choose" ] ;then
   echo "$choose is directory"
elif [ -L "$choose" ] ;then
   echo "$choose is a link"
elif [ -f "$choose" ] ;then
   echo "$choose is a common file"
else
   echo "$choose is other type"
fi

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

#!/bin/bash

read -p "input a digit:" NUM
if [[ "$NUM" =~ ^[0-9]+$ ]] ;then
   echo "$NUM is a int"
fi

循环

循环执行

  将某代码段重复运行多次

  重复运行多少次

    循环次数事先已知

    循环次数事先未知

  有进入条件和退出条件

for, while, until

for循环

for 变量名 in 列表;

do

   循环体

done

执行机制:

    依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直 到列表中的元素耗尽,循环结束
列表生成方式:
(1) 直接给出列表
   for num in 1 2 3 4 5;do echo The number is $num ;done
   The number is 1
   The number is 2
   The number is 3
   The number is 4
   The number is 5

(2) 整数列表:
   (a) {start..end}
    for num in {10..1..3};do echo The numberis $num ;done
     The numberis 10
     The numberis 7
     The numberis 4
     The numberis 1
   (b) $(seq [start [step]] end)
    for num in `seq 2 4 10`;do echo The number is $num ;done
     The number is 2
     The number is 6
     The number is 10

(3) 返回列表的命令 $(COMMAND)
(4) 使用glob,如:*.sh
   for num in "/root/bin/*.sh";do echo The filename is $num ;done
    The filename is /root/bin/*.sh
(5) 变量引用; $@独立, $*整体(位置变量)

多行重定向

练习:
用for实现
1、打印国际象棋
for i in {1..8};do
    for j in {1..4};do
        if [ $[i%2] -eq 0 ];then 
            echo -e "\033[1;41m \033[0m\e[1;43m \e[0m\c"
       else
            echo -e "\e[1;43m \e[0m\e[1;41m \e[0m\c"
       fi
    done
    echo
done

 \c=-n默认不转行

\e  \e[0m=\033  \033[0m颜色提示符

2、添加10个用户user1-user10,密码为magedu
for i in {1..10};do 
if id $i &> /dev/null ;then

    echo "user$i is exist"
else
    useradd user$i &>/dev/null
    echo "magedu" | passwd --stdin user$i &>/dev/null
    echo "user $i add successful"
fi
done

注:批量删除用户for i in {1..10};do userdel -r(删除家目录) user$i;done

3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,
以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop
S66filename start
#!/bin/bash
for i in $(ls /etc/rc.d/rc3.d/);do
        if [[ $i =~ ^K.* ]];then
                echo "$i stop"
        elif [[ $i =~ ^S.* ]];then
                echo "$i start"
        fi
done
4、编写脚本,提示输入正整数n的值,计算1+2+…+100的总和
#!/bin/bash

declare -i sum=0 n=100
    for i in {1..100};do
    let sum=sum+i | sum+=i
done
echo sum=$sum
unset sum
5、计算100以内所有能被3整除的整数之和
#!/bin/bash
sum=0
for i in {1..100};do
    if [ $[$i%3] -eq 0 ];then
    let sum+=$i
    fi  
done
echo $sum
6、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态
net=192.168.140 
   for i in {1..254};do
     { if ping -c1 -w1 $net .$i &> /dev/null ;then
     echo $net.$i is up
   else
    echo $net.$i is down
    fi; } & 并行在后台执行
done
wait

7、打印九九乘法表
#!/bin/bash

for i in {1..9};do 
   for j in `seq 1 $i`;do
       result=$[$j*$i]
       echo -e "$jx$i=$result \c"
   done
   echo
done

8、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字
母,如:1AbCdeFgH.html
取随机字母openssl rand -base64 20 | tr -dc '[:alpha:]' | head -c8
9、打印等腰三角形
*的个数=line*2-1
空格=总line-当前line
#!/bin/bash
read -p "Please input lines:" L
for i in `seq ${L}`;do
    for (( j=${L};j>i;j-- ));do
        echo -n " "
    done
    for j in `seq 1 $i`;do
        echo -n "*"
    done
    for (( n=1;n<i;n++ ));do
    echo -n "*"
    done
    echo " "
done

 打印等腰三角形并且颜色随机

#!/bin/bash
read -p "Please input lines:" L for i in `seq ${L}`;do for j in `seq $[$L-i]`;do echo -n " " done for k in `seq $[i*2-1]`;do let color=$RANDOM%7+31 echo -ne "\e[1;5;${color}m*\e[0m" done echo done

while循环

while 条件;do
     循环体
  done
条件(CONDITION):循环控制条件;进入循环之前,先做一次判断;每次循环之后会再次做判断;条件为"ture",
则执行一次循环;直到条件测试状态为“false”终止循环。

因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地 被修正

进入条件:CONDITION为true

退出条件:CONDITION为false
练习:
1
、编写脚本,求100以内所有正奇数之和 #!/bin/bash
declare
-i sum=0 i=1 while [ $i -le 100 ];do let sum=sum+i let i=i+2 done echo sum=$sum 2、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机 在线状态,并统计在线和离线主机各多少

#!/bin/bash

net=192.168.140
let num=1
x=0(up的主机)
y=0(down的主机数)
while [ ${num} -le 254 ];do
ping -c1 -w1 "${net}.${num}" &>/dev/null
  if [ $? -eq 0 ];then
    echo "${net}.${num} is up"
    x=$(($x+1))
  else
    echo "${net}.${num} is down"
    y=$(($y+1))
  fi
num=$(($num+1))
done
echo "total ${x} hosts are up"
echo "total ${y} hosts are down "

3、编写脚本,打印九九乘法表

#!/bin/bash

declare -i i=1
while [ $i -le 9 ];do
    declare -i j=1
    while [ $j -le $i ];do
       result=$[$i*$j]
       echo -e "${j}x${i}=$result\t\c" \t是产生空格并对齐;\c是不换

       let j++

    done
    echo
    let i++
done

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

#!/bin/bash

declare -i a=0
max=0
min=$RANDOM
while [ $a -le 9 ];do
num=$RANDOM
  if [ $num -le $max ];then
    if [ $num -le $min ];then
      min=$num
      fi
  else
      max=$num
  fi
  let a++:q!:
done
echo "the min number is $min,the max number is $max"

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

#!/bin/bash

let i=0
while [ $i -le 15 ];do
  for ((j=0;j<4;j++));do
    if [ $[i%4] -eq 0 -o $[i%4] -eq 1 ];then
      echo -e "\033[1;41m \033[0m\033[1;47m \033[0m\c"
    else
      echo -e "\033[1;47m \033[0m\033[1;41m \033[0m\c"

    fi
  done
  echo
  let i++
done

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

猜你喜欢

转载自www.cnblogs.com/yaun1498078591/p/9005279.html