当前位置: 首页 > news >正文

Linux学习之路-Linux-循环 for、while【10】---20171223

循环

循环执行

将某代码段重复运行多次
重复运行多少次

循环次数事先已知
循环次数事先未知

有进入条件和退出条件

for, while, until

for循环

  • 用法:

    for NAME [in WORDANDS; S ...]; do COMMdone

    for 变量名 in 列表;do 
    循环体
    done
  • 执行机制:

    依次将列表中的元素赋值给“变量名”; 每次赋值后即执 行一次循环体; 直到列表中的元素耗尽,循环结束

  • 列表生成方式:

    直接给出列表
    整数列表:

    {start..end}
    $(seq [start [step]] end)

    返回列表的命令

    $(COMMAND)

    使用glob,如:.sh
    变量引用; $@, $

  • 练习
1、判断/var/目录下所有文件的类型  --->在做一次
#!/bin/bash
for i in /var/* ;do
if [ -b $i ];then
        echo "$i是块设备"
elif [ -c $i ] ;then
        echo "$i是字符设备"
elif [ -f $i ];then
        echo "$i是普通文件"
elif [ -h $i ];then
        echo "$i是符号链接文件"
elif [ -p $i ];then
        echo "$i是管道文件"
elif [ -S $i ];then
        echo "$i是套接字文件"
elif [ -d $i ];then
        echo "$i是目录文件"
else
         echo "文件或目录不存在"
fi
done

2、添加10个用户user1-user10,密码为8位随机字符,并且把生成的用户名及密码保存到/app/newuser.txt文件中
#!/bin/bash
for i in `seq 1 5` ; do
        username=user$i
        useradd $username
        password=`openssl rand -base64 10 | head -c 8`
        echo $password | passwd --stdin $username &> /dev/null
        echo $username $password >> /app/password.txt
done
echo "ok"

3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件 ;分别读取每个文件,以K开头的输出为文件加stop,以S开头的输 出为文件名加start,如K34filename stop S66filename start   --->在做一次
#!/bin/bash
for i in /etc/rc.d/rc3.d/[SK]* ;do
if [ $(basename $i | cut -c1) == "K" ] ;then
    echo "`basename $i` stop"
else
    echo "`basename $i` start"
fi
done

4、编写脚本,提示输入正整数n的值,计算1+2+...+n的总和
#!/bin/bash
read -p "Please input a positive integer: " num
for i in `seq 1 $num` ; do
        let sum+=$i
done
echo $sum

5、计算100以内所有能被3整除的整数之和
#!/bin/bash
for i in `seq 0 3 100` ; do
        let sum+=$i
done
echo $sum      ------>1683

6、计算100以内所有不能被3整除的整数之和
for i in `seq 1 100` ; do
        if [ "$[i%3]" -ne 0 ] ; then
                let sum+=$i
        fi
done
echo $sum        ------>3376

7、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态
#!/bin/bash
> /app/ip.log
read -p "Please input the network(eg:172.18.1.0): " network
[[ "$network" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] || { echo "Please input a legal IP " ; exit 250; }    ----->**一定要注意250后的分号,机器容易忽略的位置**
net=`echo $network | cut -d. -f 1-3`
for i in {1..254} ; do
        {
        if ping -c 1 -w 1 $net.$i &> /dev/null ; then
                echo $net.$i is up | tee -a /app/ip.log
        else
                echo $net.$i is down
        fi
        }&
done
wait

8、打印九九乘法表
#!/bin/bash
for i in `seq 1 9` ; do
        for j in `seq $i` ; do
                echo -e "${j}x${i}=$[i*j]\t\c"
        done
        echo
done

9、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html
#!/bin/bash
for i in {1..10} ; do
        touch /testdir/"$i"`openssl rand -base64 100 | tr -dc '[:alpha:]' | head -c 8`.html
done

10、打印等腰三角形
#!/bin/bash
read -p "Please enter a number: " x
for i in `seq $x` ; do
        let space=$x-$i
        let xing=2*$i-1
        for j in `seq $space` ; do
                echo -e " \c"
        done
        for k in `seq $xing` ; do
                echo -e "*\c"
        done
        echo
done

until循环

  • 用法
    until CONDITION; do 
       循环体
    done
    进入条件: CONDITION 为false 
    退出条件: CONDITION 为true

循环控制语句continue

  • continue用于循环体中
  • continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
  • 用法:
    while CONDTIITON1; do
      CMD1
      ...
      if CONDITION2; then
            continue 
            fi
     CMDn
     ... 
    done

循环控制语句break

  • break用于循环体中
  • break [N]:提前结束第N层循环,最内层为第1层
  • 用法:
    while CONDTIITON1; do 
        CMD1
        ...
        if CONDITION2; then
                 break 
       fi
       CMDn
       ... 
    done

循环控制shift命令

  • shift [n]
  • 用于将参量列表 list 左移指定次数,缺省为左移一次。
  • 参量列表 list 一旦被移动,最左端的那个参数就从列表中删 除。while 循环遍历位置参量列表时,常用到 shift
  • ./doit.sh a b c d e f g h
  • ./shfit.sh a b c d e f g h
示例:doit.sh
#!/bin/bash
# Name: doit.sh
# Purpose: shift through command line arguments # Usage: doit.sh [args]
while [ $# -gt 0 ] # or (( $# > 0 )) ; do
       echo $*
       shift 
done

示例:shift.sh
#!/bin/bash
#step through all the positional parameters 
until [ -z "$1" ] ; do
       echo "$1"
       shift 
done
echo

for 特殊用法

  • 双小括号方法,即((...))格式,也可以用于算术运算
  • 双小括号方法也可以使bash Shell实现C语言风格的变量操作

    I=10
    ((I++))

  • 控制变量初始化:仅在运行到循环代码段时执行一次
  • 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
  • 用法

    for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
    do
         循环体
    done
    for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
        Arithmetic for loop.
    
       Equivalent to
                    (( EXP1 ))
                    while (( EXP2 )); do
                                COMMANDS
                                (( EXP3 ))
         done

    Linux学习之路-Linux-循环 for、while【10】---20171223

示例:
1、求1-100的和
写法1
#!/bin/bash
sum=o
for ((i=1;i<=100;i++)) ; do
        let sum+=i
done
echo sum=$sum

写法2
for ((sum=0,i=1;i<=100;i++)) ; do
        let sum+=i
done
echo sum=$sum

2、求1-100中 3 的整数倍的和
用for写法
for ((sum=0,i=0;i<=100;i+=3)) ; do
        let sum+=i
done
echo sum=$sum
用while写法
sum=0
i=0
while [ "$i" -le 100] ; do
        let sum+=i
        let i+=3
done
echo sum=$sum

3、打印9x9表
for ((i=1;i<=9;i++)) ; do
        for ((j=1;j<=i;j++)) ; do
                echo -ne "${j}x${i}=$[$i*$j]\t" ;
        done
        echo
done
  • 练习
1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发 现用户hacker登录,则将登录时间和主机记录于日志 /var/log/login.log中,并退出脚本 --->在做一次
#!/bin/bash
username=cent
{
while true ;do
    if who | egrep "^\b$username\b" &> /dev/null ;then
        who | egrep "^\b$username\b" >> /var/log/login.log
        echo "$username 已登录"
        echo "fuck ,go out my system" | write $username
    else
        echo "$username 已下线"
    fi
    sleep 3
done
}

2、随机生成10以内的数字,实现猜字游戏,提示比较大或小 ,相等则退出
suiji=`echo $[$RANDOM%10+1]`
read -p "Please input a number in 1-10: " num
until [[ "$num" -eq "$suiji" ]] ; do
        if [[ "$num" -lt "$suiji" ]] ; then
                read -p "less than random: " num
        else
                read -p "much than random: " num
        fi
done
echo -e "\e[32mCongratulations! The random is $suiji!\e[37m"

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

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

while 循环

  • 用法

    while CONDITION; do 
         循环体
    done

    CONDITION:循环控制条件;进入循环之前,先做一次判 断;每一次循环之后会再次做判断;条件为“true”,则执行 一次循环;直到条件测试状态为“false”终止循环
    因此:CONDTION一般应该有循环控制变量;而此变量的值 会在循环体不断地被修正
    进入条件:CONDITION为true
    退出条件:CONDITION为false

  • 创建无线循环
    while true; do 
         循环体
    done
  • while循环的特殊用法

    遍历文件的每一行

    while read line; do
    循环体
    done &lt; /PATH/FROM/SOMEFILE
    依次读取/PATH/FROM/SOMEFILE文件中的每一行,
    且将行赋值给变量line
    示例:
    扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填 充用户名和单位电话为62985600,并提示该用户的GECOS信 息修改成功。
  • 练习
1、编写脚本,求100以内所有正奇数之和
#!/bin/bash
i=1
while [ "$i" -le 100 ] ; do
        if [ $[$i%2] -ne 0 ] ; then
                let sum+=$i
        fi
        let i++
done
echo $sum

2、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态,并统计在线和离线主机各多少
#!/bin/bash
read -p "Please input the network(eg:172.18.0.1): " network
[[ "$network" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-9])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-9])$ ]] || { echo "Please input a legal IP " ; exit 250 ; }
net=`echo $network | cut -d. -f 1-3`
i=1
up=0
down=0
while [ "$i" -le 254 ] ; do
        ping -c 1 -w 1 $net.$i &> /dev/null && { echo $net.$i is up ; let ++up ; } || { echo $net.$i is down ; let down++ ; }
        let i++
done
wait
echo i=$i
echo up host is $up
echo down host is $down

3、编写脚本,打印九九乘法表
#!/bin/bash
i=1
j=1
while [ $i -le 9 ] ;do
    while [ $j -le $i  ] ;do
        echo -ne "${j}x${i}=$[i*j]\t"
        let j+=1
    done
    let i+=1
    j=1
    echo
done

4、编写脚本,利用变量RANDOM生成10个随机数字,输出 这个10数字,并显示其中的最大值和最小值
#!/bin/bash
let i=0,min=max=$RANDOM
echo "$min "
while [ $i -lt 9  ];do
    ran=$RANDOM
    echo "$ran "
    if [ $ran -ge $max ];then 
        let max=ran
    fi
    if [ $ran -le $min ];then
        let min=ran
    fi
    let i+=1
done
echo "最大值是 $max ,最小值是 $min"

5、编写脚本,实现打印国际象棋棋盘
#!/bin/bash
let x=y=1
h=8
while [ $x -le $h ];do
    while [ $y -le $h ];do
        if [ $[(x+y)%2] -eq 0 ]  ;then
            echo -en "\033[47m  \033[0m"
        else
            echo -en "\033[40m  \033[0m"
        fi
    let y+=1
    done
    echo
let x+=1,y=1
done

6、后续六个字符串:efbaf275cd、4be9c40b8b、 44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63 是通过对随机数变量RANDOM随机执行命令:echo $RANDOM|md5sum|cut –c1-10 后的结果,请破解这些字符串对应的RANDOM值
 #!/bin/bash
 key_num_array=(efbaf275cd 4be9c40b8b 44b2395c46 f8c8873ce0 b902c16c8b ad865d2f63)
 for true_num in `seq 0 65535`;do
      key_num=`echo $true_num | md5sum | cut -c 1-10`
      for num in  ${key_num_array[*]}; do
             if [ "$key_num" == "$num" ];then
                   echo "$num --> $true_num" 
            fi                                                                       
     done
done

7 、检测httpd服务是否处于开启状态,如果处于关闭状态,即刻开启服务
#!/bin/bash
sleeptime=30
while true ; do
        if killall -0 httpd &> /dev/null ; then
                true
        else
                service httpd restart
                time=`date +"%F %T"`
                echo "At $time httpd is restart" >> /app/httpd.log
        fi
        sleep $sleeptime
done

8、检测磁盘利用率,如果大于80,就发出警报,每5分钟检测一次
第一种方法:
while true ; do
        df -h | grep "/dev/sd" | while read disk ; do
                per=`echo $disk | sed -r 's/.* (.*)%.*/\1/'`
                part=`echo $disk | cut -d" " -f1`
                [ "$per" -gt 80 ] && echo "$part will be full,over 80%"
        done
        sleep 300
done
第二种方法-做成计划任务调用脚本,脚本内容如下
used=10
df -h | grep "/dev/sd" | while read disk ; do
        per=`echo $disk | sed -r 's/.* (.*)%.*/\1/'`
        part=`echo $disk | cut -d" " -f1`
        [ "$per" -gt "$used" ] && echo "$part will be full,over ${used}%"
done

select循环与菜单

  • select 循环主要用于创建菜单,按数字顺序排列的 菜单项将显示在标准错误上,并显示 PS3 提示符,等待用户输入
  • 用户输入菜单列表中的某个数字,执行相应的命令
  • 用户输入被保存在内置变量 REPLY
  • 用法
    select variable in list 
    do
           循环体命令
    done
  • select 是个无限循环,因此要记住用 break 命令退 出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
  • select 经常和 case 联合使用
  • 与 for 循环类似,可以省略 in list,此时使用位置 参量
示例:
1、用while完成的菜单
#!/bin/bash
cat <<EOF
1 yxrs
2 gbjd
3 lzjd
4 lamian
5 huimian
6 yangroutang
7 quit
EOF
while read -p "Please choose the menu number: " menu ; do
        case $menu in
        1|2)
                echo The price is 20
                ;;
        3|6)
                echo The price is 25
                ;;
        4|5)
                echo The price is 15
                ;;
        7)
                break
                ;;
        *)
                echo "Please choose again"
                ;;
        esac
done

2、用select 完成
PS3="Please choose the menu number: "
select menu in gbjd yxrs lamian huimian baoyu quit ; do
        case $menu in
        gbjd|yxrs)
                echo The price is 25
                ;;
        lamian|huimian)
                echo The price is 15
                ;;
        baoyu)
                echo The price is 100
                ;;
        quit)
                break
                ;;
        *)
                echo "Try choose again"
                ;;
        esac
done

3、select 与 $REPLY 配合
PS3="Please choose the menu number: "
select menu in gbjd yxrs lamian huimian baoyu quit ; do
        case $REPLY in
        1|2)
                echo The price is 25
                ;;
        3|4)
                echo The price is 15
                ;;
        5)
                echo The price is 100
                ;;
        6)   
                break
                ;;
        *)
                echo "Try choose again"
                ;;
        esac
done

trap 信号捕捉

  • trap '触发指令' 信号 自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作
  • 用法

    trap '' 信号

    忽略信号的操作

    trap '-' 信号

    恢复原信号的操作

    trap -p

    列出自定义信号操作

  • trap示例
#!/bin/bash
trap 'echo “signal:SIGINT"' int 
trap -p
for((i=0;i<=10;i++))
do
       sleep 1
       echo $i 
done
trap '' int
trap -p 
for((i=11;i<=20;i++)) 
do
      sleep 1
      echo $i 
done
trap '-' int
trap -p 
for((i=21;i<=30;i++)) 
do
     sleep 1
     echo $i 
done

#!/bin/bash
trap `echo Do not break` INT
fo i in {1..10} ; do
      echo $i
            sleep 0.5
done

转载于:https://blog.51cto.com/exia00linux/2058422

相关文章:

  • 函数式 Java 到函数式 Kotlin 的转换
  • 23.2. 基础操作
  • Kubernetes系统架构简介[转]
  • Jenkins+Jmeter持续集成笔记(三:集成到Jenkins)
  • [译]使用 Siesta 处理 Swift 网络请求
  • 33.3. nanomsg
  • Salesforce收购数据库创业公司Attic Labs
  • 数组 类型 在 存储过程中 使用
  • 基于TableStore/MaxCompute的数据采集分析系统介绍
  • think php框架接入微信支付中需要注意的问题(php 小白适用)
  • 第一章
  • 分布式文件系统FastDFS如何做到高可用
  • Vmware Workstation及Centos6.8 的安装
  • Android系统shell中的clear命令实现【转】
  • 剑指offer15
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 77. Combinations
  • Docker下部署自己的LNMP工作环境
  • eclipse(luna)创建web工程
  • es6
  • Javascript基础之Array数组API
  • js写一个简单的选项卡
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • React组件设计模式(一)
  • Unix命令
  • webpack4 一点通
  • 大型网站性能监测、分析与优化常见问题QA
  • 基于 Babel 的 npm 包最小化设置
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 什么软件可以剪辑音乐?
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 通过npm或yarn自动生成vue组件
  • 微信小程序填坑清单
  • 责任链模式的两种实现
  • 你对linux中grep命令知道多少?
  • 选择阿里云数据库HBase版十大理由
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • (1)常见O(n^2)排序算法解析
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (多级缓存)缓存同步
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (九)信息融合方式简介
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • **PHP分步表单提交思路(分页表单提交)
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net core 6.0 升8.0
  • .net 调用php,php 调用.net com组件 --
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET微信公众号开发-2.0创建自定义菜单
  • @开发者,一文搞懂什么是 C# 计时器!