shell循环控制

bash脚本编程:

         编程语言:

                   数据结构

                   顺序执行

                   选择执行

                            条件测试

                                     运行命令或[[expression ]]

                                               执行状态返回值

                            if

                            case

                   循环执行

                            将某代码重复运行多次

                            重复运行多少次?

                                     循环次数事先已知

                                     循环次数事先未知

                                     必须有进入条件和退出条件

                            for、while、until

                   函数:结构化编程及代码重用

                            function

         for循环语法:

                   forname in list; do

                            循环体

                   done

                  

                   列表生成方式:

                (1)      整数列表

                    {start..end}

                    $(seq start [[ step ]end])

                (2)      glob

                    /etc/rc.d/rc3.d/K*

                (3)      命令

通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态

#!/bin/bash

net="172.16.250"
uphosts=0
downhosts=0
for i in {1..20}; do
        ping -c 1 -w 1 ${net}.${i} &> /dev/null
        if [ $? -eq 0 ]; then
                echo "${net}.${i} is up "
                let uphosts++
        else
                echo "${net}.${i} is down "
                let downhosts++
        fi
done

echo "up hosts: ${uphosts}"
echo "down hosts: ${downhosts}"

练习:打印九九乘法表(for和while)

#!/bin/bash
for j in  {1..9}; do
        for i in $(seq 1 ${j}); do
                echo -n "${i}*$[j]=$[${i}*${j} ] "
        done
        echo
done
#!/bin/bash

for ((j=1;j<=9;j++)); do
        for((i=1;i<=j;i++)); do
                echo -e -n "${i}*${j}=$[${i}*${j}]\t"
        done
        echo 
done

练习:利用random生成10个数字,并显示其中的最大者和最小者

#!/bin/bash


declare -i max=0
declare -i min=0
declare -i i=1

max=$RANDOM
min=$max
while [ $i -le 10 ]; do
        rand=$RANDOM
        if [ $rand -gt $max ]; then
                max=$rand
        fi
        if [ $rand -lt $min ]; then
                min=$rand
        fi
        let i++
done


echo "max:$max "
echo "min:$min"

bash编程:

         whilecondition; do

                   循环体

         done

         进入条件:condition为true

         退出条件:false

         untilcondition; do

                   循环体

         done

         进入条件:false

         退出条件:true

示例:求100以内所有正整数之和

#!/bin/bash

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

循环控制语句:

              continue:

                            while condition; do

                                          cmd1

                                          …

                                          ifcondition2; do

                                                        continue

                                          fi

                                          cmd2

                                          …

                            break

              break [N]:提前结束循环

                            while condition; do

                                          cmd1

                                          …

                                          ifcondition2; do

                                                        break

                                          fi

                                          cmd2

                                          …

              break

示例1:求100以内所有偶数之和,要求循环遍历100以内的所有正整数

#!/bin/bash

declare -i i=1
declare -i sum=0
until [ $i -gt 100 ]; do
        let i++
        if [ $[$i%2] -eq 1 ]; then
                continue
        fi
        let sum=$sum+$i
done
echo "even sum:$sum"

创建死循环

示例2:

每隔3秒钟到系统上获取已经登录的用户的信息,如果doctker登录了,则记录在日志中,并退出

#!/bin/absh
read -p "enter a user name" username
while true; do
        if who | grep "^$username" &> /dev/null; then
                break
        fi
        sleep 3
done
echo "$usernmae logined" >> /tmp/userlogin.log

第二种,until

#!/bin/absh
read -p "enter a user name" username
until false; do
        if ! who | grep "^$username" &> /dev/null; then
                continue
        fi
        sleep 3
done
echo "$usernmae logined" >> /tmp/userlogin.log

while循环的特殊语法(遍历文件的每一行)

while read line; do
done  < /path/from/somefile

一次读取/path/from/somefile文件中的每一行,且将行赋值给变量line

示例:找出id号为偶数的所有用户,显示其用户名和id号

#!/bin/bash

while read line; do
        if [ $[`echo $line | cut -d: -f3` % 2] -eq 0 ] ; then
                echo -e -n "username:`echo $line | cut -d: -f1`\t"
                echo "uid:`echo $line | cut -d: -f3`"
        fi
done < /etc/passwd

for循环的特殊格式:

             for((控制变量初始化;条件判断表达式;控制变量的修正表达式)); do

                          循环体

            done

示例:求100以内所有正整数之和

#!/bin/bash
declare -i sum=0
for((i=1;i<=100;i++)); do
        sum=$sum+$i
done
echo "sum:$sum"

示例:

打印九九乘法表:

#!/bin/bash
for ((j=1;j<=9;j++)); do
        			for((i=1;i<=j;i++)); do
               			echo -e -n "${i}*${j}=$[${i}*${j}]\t"
        			done
        			echo 
done

练习:

 写一个脚本,完成如下任务

(1)           显示一个如下的菜单:

            a)         cpu)show cpu information

            b)         mem)show memory information

            c)          disk)show disk information

(2)           提示用户选择选项

(3)           显示用户选择的内容

进一步地:

              用户选择,并显示完成后不退出脚本,而是提示用户继续选择其他内容,直到使用quit方式退出

#!/bin/bash

cat << EOF
cpu) show cpu information
mem) show memory information
disk) show disk information
quit) quit
--------------------------------------------
EOF
read -p "enter a option:" option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
        read -p "wrong option,enter again:" option
done

if [ "$option" == 'cpu' ]; then
        lscpu
elif [ "$option" == 'mem' ]; then
        cat /proc/meminfo
elif [ "$option" == 'disk' ]; then
        fdisk -lh
else
        echo "quit"
        exit 0
fi

条件判断:case语句

              case 变量引用 in

              pat1)

                            分支1

                            ;;

              part2)

                            分支2

                            ;;

              *)

                            默认分支

                            ;;

              esac

case写法:
#!/bin/bash

cat << EOF
cpu) show cpu information
mem) show memory information
disk) show disk information
quit) quit
--------------------------------------------
EOF
read -p "enter a option:" option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
	read -p "wrong option,enter again:" option
done

case "$option" in
cpu)
	lscpu
	;;
mem)
	cat /proc/meminfo
	;;
disk)
	fdisk -l
	;;
*) 
	echo "quit.."
	exit 0
	;;
esac

练习:写一个脚本,完成如下要求

(1)           脚本可接受参数:start,stop,restart,status

(2)           若果参数非此四者之一,提示格式后报错退出

(3)           如果是start,则创建/var/lock/syssubsys/script_name并显示启动成功

如果事先已经启动过一次,该如何处理

(4)           如果是stop,则删除/var/lock/syssubsys/script_name,并显示“停止完成”

考虑如果事先已停止过,该如何处理

(5)           如果是restart,则先stop,再start

考虑如果本来没有restart,如何处理

(6)           如果是status,则

如果/var/lock/syssubsys/script_name文件存在,则显示“script_name isrunning…”

如果/var/lock/syssubsys/script_name文件不存在,则显示“script_name isstopped…”

              其中,script_name为当前脚本名:

#!/bin/bash
#chkconfig: - 88 12
description:test service script
prog=$(basename $0)
lockfile=/var/lock/subsys/$prog
start(){
	if [ -e $lockfile ]; then
		echo "$prog is aleady running"
		return 0
	else 
		touch $lockfile
		[ $? -eq 0 ] && echo "starting $prog finished."

	fi
}

stop(){
	if [ -e $lockfile ]; then
		rm -f $lockfile && echo "stop $prog ok."
	else
		echo "$prog is stopped yet."
	fi

}
status(){
	if [ -e $lockfile ]; then 
		echo "$prog is running."\

	else
 		echo "$prog is stopped."

	fi
}

usage(){
	echo "usage:$prog {start|stop|restart|status}"

}

if [ $# -lt 1 ]; then
	usage
	exit 1
fi

case $1 in
start)
	start
	;;
stop)
	stop
	;;
restart)
	stop
	start
	;;
status)
	status
	;;
*)
	usage
	;;
esac

case支持glob分割的通配符:

         *:任意长度任意字符

         ?:任意单个字符

         []:任意范围内的单个字符

         a|b:a或b

function:函数

         过程式编程:代码重用

                   模块化编程

                   结构化编程

         语法一:

                   functionf_name {

                            函数体

}

         语法二:

                   f_name(){

                            函数体

}

         调用:函数只有调用才会执行

                  调用:给定函数名

                            函数出现的地方,会被自动替换为函数代码

                   函数的生命周期,被调用时创建,返回时终止

                            return命令返回自定义状态结果

                                     0:成功

                                     1-255:失败

#!/bin/bash
username='myuser'
function adduser {
        	if id $username &> /dev/null; then
                	echo "$username has exists"
                	return 1
        	else
                	useradd $username
                	[ $? -eq 0 ] && echo "$username had created." && return 0
        	fi
}
adduser













你可能感兴趣的:(linux)