shell(二)

for循环

语法结构

 列表循环

列表for循环:用于将一组命令执行已知的次数,下面给出了for循环语句的基本格式:

for variable in {list}
     do
          command 
          command
          …
     done
或者
for variable in a b c
     do
         command
         command
     done

语法结构举例说明:

 1001  for i in {1..10};do echo $i;done
 1002  for i in {1..10..2};do echo $i;done     ======》13579
 1003  for i in {10..1};do echo $i;done
 1004  for i in {10..1..-2};do echo $i;done
 1005  for i in {10..1..2};do echo $i;done
 1006  for i in `seq 10`;do echo $i;done
 1007  for i in `seq 1 10`;do echo $i;done
 1008  for i in `seq 1 2 10`;do echo $i;done
 1009  for i in `seq 10 1`;do echo $i;done
 1010  for i in `seq 10 -2 1`;do echo $i;done

不带列表循环

不带列表的for循环执行时由用户指定参数和参数的个数,下面给出了不带列表的for循环的基本格式:

for variable
    do
        command 
        command
        …
   done

类C风格的for循环

for(( expr1; expr2; expr3 ))
    do
        command
        command
        …
    done
​
expr1:定义变量并赋初值
expr2:决定是否进行循环(条件)
expr3:决定循环变量如何改变


#语法结构举例说明:

 1011  for ((i=1;i<=10;i++));do echo $i;done
 1012  for ((i=1;i<=10;i+=2));do echo $i;done
 1013  for ((i=2;i<=10;i+=2));do echo $i;done

示例

demo1:计算1到100的奇数之和,方法不止一种

方法1:
#!/bin/bash
sum=0
for i in {1..100..2}
 do
        let sum=$i+$sum
 done
echo "1-100的奇数和为:$sum"
​
方法2:
#!/bin/bash
sum=0
for i in `seq 1 2 100`
 do
    sum=$[$sum+$i]
 done
echo "1-100的奇数和为:$sum"
​
方法3:
#!/bin/bash
sum=0
for i in {1..100}
 do
    if [ $[$i%2] -ne 0 ];then
        sum=$(($sum+$i))
    fi
 done
echo "1-100的奇数和为:$sum"
​
方法4:
#!/bin/bash
sum=0
for i in {1..100}
 do
    if [ $[$i%2] -eq 0 ];then
        continue
        else
        sum=$[$sum+$i]
    fi
 done
echo "1-100的奇数和为:$sum"
​
方法5:
#!/bin/bash
sum=0
for i in {1..100}
 do
[ $[$i%2] -eq 0 ] && continue ||sum=$[$sum+$i]
 done
echo "1-100的奇数和为:$sum"

循环控制

continue:继续。表示循环体内下面的代码不执行,重新开始下一次循环

break:打断。马上停止执行本次循环,执行循环体后面的代码

exit:表示直接跳出程序

demo2:输入一个正整数,判断是否为质数(素数) 质数:只能被1和它本身整除的数叫质数。

方法1:
#!/bin/bash
read -p "请输入一个正整数字:" number
[ $number -eq 1 ] && echo "$number不是质数" && exit
[ $number -eq 2 ] && echo "$number是质数" && exit
for i in `seq 2 $[$number-1]`
    do
     [ $[$number%$i] -eq 0 ] && echo "$number不是质数" && exit
    done
echo "$number是质数" && exit

方法2:
#!/bin/bash

yes='该数字,是质数'
no='该数字,不是质数'
read -p '请输入一个数字:' num;

[[ $num == 1 ]] && echo $no && exit;
[[ $num == 2 ||  $num == 3 ]] && echo $yes && exit;

for ((i=2;i<=$[$num/2];i++))
        do
                if [ $[$num%$i] -eq 0  ]
                        then echo $no;exit;
                fi
        done

echo $yes;

demo3:批量加5个新用户,以u1到u5命名,并统一加一个新组,组名为class,统一改密码为123

方法1:
#!/bin/bash
grep -w class /etc/group &>/dev/null
[ $? -ne 0 ] && groupadd class
for i in {1..5}
 do
    useradd -G class u$i && echo 123|passwd --stdin u$i
 done

方法2:
#!/bin/bash
grep -w class /etc/group &>/dev/null
[ $? -ne 0 ] && groupadd class
for (( i=1;i<=5;i++))
    do
    useradd -G class u$i && echo 123|passwd --stdin u$i
    done

demo

1、批量新建5个用户stu1~stu5,要求这几个用户的家目录都在/rhome.提示:需要判断该目录是否存在

#!/bin/bash
#判断/rhome目录是否存在
#test ! -d /rhome && mkdir /rhome
[ ! -d /rhome ] && mkdir /rhome
for ((i=1;i<=5;i++))
do
    useradd -d /rhome/stu$i stu$i && echo 123|passwd --stdin stu$i
done

2、写一个脚本,局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里(如果例举整个网段的254个IP花的时间比较长,可以只分类10个ip192.168.1.10~20) 这只是一个局域网内机器检查通讯的一个思路。

#!/bin/bash
ip=10.1.1.
for i in {1..5}
 do
    ping -c 1 $ip$i &>/dev/null
    [ $? -eq 0 ] && echo "$ip$i" >> /tmp/ok.ip || echo "$ip$i" >> /tmp/faild.ip
 done

3、输入一个年份,判断是否是润年(能被4整除但不能被100整除,或能被400整除的年份即为闰年。)

#!/bin/bash
read -p "Please input year:(2017)" year
if [ $[$year%4] -eq 0 -a $[$year%100] -ne 0 ];then
    echo "$year is leap year"
elif [ $[$year%400] -eq 0 ];then
    echo "$year is leap year"
else
    echo "$year is not leap year"
fi

until循环

条件为真就退出循环;条件为假就死循环

until expression   [ 1 -eq 1 ]  (( 1 >= 1 ))
    do
        command
        command
        ...
    done    

示例1:使用until打印1-5

 1085  for ((i=1;i<=5;i++));do echo $i;done
 1086  i=1;until [ $i -gt 5 ];do echo $i;let i++;done
 1088  i=1;until [ $i -gt 5 ];do echo $i;let i++;done
 1089  for ((i=5;i>=1;i--));do echo $i;done
 1090  i=5;until (( $i < 1 ));do echo $i;let i--;done
 1091  i=1;until (( $i > 5 ));do echo $[6-$i];let i++;done

示例2:使用until改写批量创建用户脚本

#!/bin/bash
#判断/rhome目录是否存在
#test ! -d /rhome && mkdir /rhome
[ ! -d /rhome ] && mkdir /rhome
i=1
until [ $i -gt 5 ]
do
    useradd -d /rhome/stu$i stu$i && echo 123|passwd --stdin stu$i
    #userdel -r stu$i
    let i++
done

while循环

条件为真就进入死循环;条件为假就退出循环

while expression  [ 1 -eq 1 ] (( 1 > 2 ))
  do
     command
     command
     ...
 done
1106  i=1;until (( $i > 5 ));do echo $i;let i++;done
 1107  i=1;while (( $i <= 5 ));do echo $i;let i++;done
 1108  i=5;while [ $i -ge 1 ];do echo $i;let i--;done
 1109  i=1;while [ $i -le 5 ];do echo $[6-$i];let i++;done

示例:

写一个30秒同步一次时间同步服务器10.1.1.1的脚本,如果同步失败,则进行邮件报警,每次失败都报警;同步成功,也进行邮件通知,但是成功100次才通知一次。

#!/bin/bash
count=0
ntp=10.1.1.1
while true
 do
  rdate -s $ntp &>/dev/null
  if [ $? -ne 0 ];then
        echo "system date faild" |mail -s 'check system date' root@localhost
  else
        let count++
        [ $count -eq 3 ] && echo "system date ok" |mail -s 'check date' root@localhost && count=0
  fi
        sleep 3

 done


方式2:
#!/bin/bash
count=0
ntpserver=10.1.1.10
while true
do
    rdate -s $ntpserver &>/dev/null
    [ $? -ne 0 ] && echo check system date failed |mail root@localhost || let count++
    [ $count -eq 5 ] && echo check system date sccuess |mail root@localhost && count=0
sleep 5
done 

随机数

bash默认有一个$RANDOM的变量        默认是0~32767。使用set |grep RANDOM    查看上一次产生的随机数
echo $RANDOM

产生0~1之间的随机数
echo $[$RANDOM%2]

产生0~2之间的随机数
echo $[$RANDOM%3]

产生0~3之间的随机数
echo $[$RANDOM%4]
。。。。
产生0~9内的随机数
echo $[$RANDOM%10]

产生0~100内的随机数
echo $[$RANDOM%101]


产生50-100之内的随机数
echo $[$RANDOM%51+50]

产生三位数的随机数
echo $[$RANDOM%900+100]

 

原文地址:https://www.cnblogs.com/ycg-blog/p/12748178.html