shell编程(四)之循环控制语句(for,while,until,break,continue,case)

for循环

语法:for NAME in LIST; do
    循环体
   done

列表生成方式:
1.整数列表
  {start..end}
  $(seq,[start [step]] end)
2.glob
  /etc/rc.drc3.d/K*
3. 命令
  比如ls

1.写一个脚本:
(1)列出当前系统识别到的所有磁盘设备:
(2)如磁盘数量为1,则显示其空间使用信息:
如果大于1,则显示最后一个磁盘上的空间使用信息

 #! /bin/bash
#
diskcount=`fdisk -l | grep "^磁盘 /dev/[sh]d[a-z]" | wc -l`
lastdisk=`fdisk -l | grep -o "^磁盘 /dev/[sh]d[a-z]|tail -1 | cut -d' ' -f2"`
if [ $diskcount -eq ];then
fdisk -l /dev/[hs]d[a-z];
elif [ $diskcount -gt ];then
fdisk -l $lastdisk
fi

2. 添加10个用户,密码同用户名

#! /bin/bash
#
for i in {..};do
if id user$i &> /dev/null;then
echo "用户已存在"
else
useradd user$i
if [ $? -eq ];then
echo "user$i" | passwd --stdin user$i;
echo "user add successed"
fi
fi
done

3./etc/rc.d/rc3.d目录下分别有多个以k开头和S开头的文件

分别读取每个文件,而后输出“k34filename” stop
s66filename start

#!/bin/bash
for file in /etc/rc.d/rc3.d/[KS]*;do
cname=`basename $file | cut -c1`
filename=`basename $file`
if [ $cname == "K" ];then
echo "$filename stop"
else
echo "$filename start"
fi
done

4.打印九九乘法表(for语句实现)

#!/bin/bash
for i in $(seq );do
for j in $(seq $i);do
echo -n -e "$j*$i=$[$i*$j]\t" done
echo -e "\n"
done

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

#!/bin/bash
iptmp="192.168.1"
uphosts=
downhosts=
for i in $(seq ); do ping -c -w $iptmp.$i &> /dev/null
if [ $? -eq ]; then
echo "$iptmp.$i 在线" let uphosts++
else
echo "$iptmp.$i 不在线"
let downhosts++
fi
done
echo "uphosts为$uphosts"
echo "downhosts为$downhosts"

while循环

1.求100以内所有正整数之和

#!/bin/bash
declare -i i=
declare -i sum=
while [ $i -le ];do
let sum+=$i
let i++
done
echo "1到100整数和为$sum"

2.添加10个用户

#!/bin/bash
declare -i i=
while [ $i -le ];do
if id user$i &> /dev/null; then
echo "user$i已存在"
else
if useradd user$i &> /dev/null;then
echo "user$i 添加成功"
echo "user$i" | passwd --stdin user$i &> /dev/null
else
echo "user$i 添加失败"
fi
fi
let i++
done

2.通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态(用while循环)

#!/bin/bash
iptmp=192.168.
declare -i i=
uphosts=
downhosts=
while [ $i -le ];do
if ping -c -w $iptmp.$i &> /dev/null; then
echo "主机$iptmp.$i is up"
let uphosts++
else
echo "主机$iptmp.$i is down"
let downhosts++
fi
let i++
done
echo "up hosts 有$uphosts个"
echo "down hosts有$downhosts个"

3.打印九九乘法表(while循环实现)

while实现
#!/bin/bash
declare -i i=
declare -i j= while [ $i -le ];do
while [ $j -le $i ];do
echo -n -e "$j*$i=$[$i*$j]\t"
let j++
done
echo -e "\n"
let i++
let j=
done

4.利用RANDOM生成10个随机数字,输出其中最大值和最小值

#!/bin/bash
declare -i i=
declare -i max=
declare -i min=
declare -i temp=
while [ $i -le ]; do
let temp=$RANDOM
let min=$temp
if [ $temp -gt $max ];then
let max=$temp
elif [ $temp -lt $min ];then
let min=$temp
fi
let i++ done
echo "最大值为$max,最小值为$min"

until循环

1.求100以内正整数之和:

#!/bin/bash
declare -i i=
declare -i sum= until [ $i -gt ];do
let i++
let sum+=$i
done
echo "sum为$sum"

2. 打印九九乘法表(until实现)

#!/bin/bash
declare -i i=
declare -i j=
until [ $i -gt ];do
until [ $j -gt $i ];do
echo -n -e "$j*$i=$[$i*$j]\t"
let j++
done
echo -e "\n"
let i++
let j=
done

循环控制语句(break,continue)

1. 求100以内所有偶数之和

#!/bin/bash
declare -i i=
declare -i sum=
until [ $i -gt ];do
let i++
if [ $[$i%] -eq ];then
continue
fi
let sum+=$i
done
echo "sum:$sum"

2. 每隔三秒钟判断chengkaihua这个用户登录情况

#!/bin/bash
read -p "Enter a username:" username
while true;do
if `who | grep "^$username" &> /dev/null`;then
echo "$username logged on"
fi
sleep
done

while 循环的特殊用法(遍历文件的每一行)
while read line;do
循环体
done < /PATH/TO/SOMEFILE

依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line

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

#!/bin/bash
file=/etc/passwd
while read line;do
let ids=`echo $line | cut -d: -f3`
if [ $[$ids%] -eq ];then
username=`echo $line | cut -d: -f1`
echo "用户名为$username,ID号为$ids"
fi
done < $file

for循环的特殊格式
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式));do
done

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

#!/bin/bash
declare -i sum=
for ((i=;i<=;i++));do
let sum+=$i
done
echo "sum的值为$sum"

2. 打印九九乘法表

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

练习:写一个脚本,完成如下任务:
(1) 显示一个如下菜单
cpu) show cpu information
mem) show memory information
disk) show disk information
quit) quit
(2) 提示用户选择选项
(3) 显示用户选择的内容

进一步的:
用户选择,并显示完成后不退出脚本;而是提示用户继续选择显示其他内容,知道使用quit方始退出

#!/bin/bash
cat << EOF
cpu) show cpu information
mem) show mem information
disk) show disk information
quit) quit
EOF read -p "Enter an option:" option while [[ $option != "cpu" && $option != "mem" && $option != "disk" && $option != "quit" ]];do
read -p "Wrong option,Enter again:" option
done while [ $option != "quit" ];do
read -p "Enter an option:" option
if [ $option == "cpu" ];then
lscpu
continue
elif [ $option == "mem" ];then
cat /proc/meminfo
continue
elif [ $option == "disk" ];then
fdisk -l
continue
else
echo "Quit"
exit
fi
done

case语句
case 变量引用 in
PAT1)
  分支1
  ;;
PAT2)
  分支2
  ;;
...
*)
  默认分支
  ;;
esac

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

练习:写一个脚本,完成如下任务:(case实现)
(1) 显示一个如下菜单
cpu) show cpu information
mem) show memory information
disk) show disk information
quit) quit
(2) 提示用户选择选项
(3) 显示用户选择的内容

进一步的:
用户选择,并显示完成后不退出脚本;而是提示用户继续选择显示其他内容,知道使用quit方始退出

#!/bin/bash
cat << EOF
cpu) show cpu information
mem) show mem information
disk) show disk information
quit) quit
EOF
while true; do
case $option in
"cpu")
  lscpu
  ;;
"mem")
  cat /proc/meminfo
  ;;
"disk")
  fdisk -l
  ;;
"quit")
  echo "Quit"
  exit
  ;;
esac
read -p "Enter an option:" option
if [[ $option != "cpu" && $option != "mem" && $option != "disk" && $option != "quit" ]];then
  read -p "Wrong option,Enter again:" option
fi
done

练习: 写一个脚本,完成如下要求
1.脚本可接受参数:start,stop,restart,status
2.如果参数非此四者之一,提示使用格式后报错退出
3.如果是start,则创建/var/lock/subsys/SCRIPT_NAME,并显示启动成功
考虑: 如果事先已经启动过一次,该如何处理
4.如果是stop,则删除/var/lock/subsys/SCRIPT_NAME,并显示停止完成
考虑: 如果事先已然停止过了,该如何处理
5 如果是restart,则先stop,在start
考虑:如果本来没有start,如何处理
6.如果是status,则:
如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示”SCRIPT_NAME is running“
如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示”SCRIPT_NAME is stopped“

#!/bin/bash
name=`basename $`
path=/var/lock/subsys/
read -p "Usage:start|stop|restart|status:" option
if [[ $option != "start" && $option != "stop" && $option != "restart" && $option != "status" ]];then
echo "Wrong option,Usage:start|stop|restart|status"
exit
fi
case $option in
"start")
  if [ -e $path$name ];then
    echo "$name 启动成功"
  else
    touch $path$name
    echo "$name 启动成功"
  fi
  ;;
"stop")
  if [ -e $path$name ];then
    rm -rf $path$name
    echo "$name 停止完成"
  else
    echo "$name 停止完成"
  fi
  ;;
"restart")
  if [ -e $path$name ];then
    echo "$name 启动成功"
  else
    touch $path$name
    echo "$name 启动成功"
  fi
  ;;
"stop")
  if [ -e $path$name ];then
    rm -rf $path$name
    echo "$name 停止完成"
  else
    echo "$name 停止完成"
  fi
  ;;
"restart")
  if [ -e $path$name ];then
    rm -rf $path$name
    touch $path$name
    echo "重启完成"
else
  touch $path$name
  echo "重启完成"
  fi
  ;;
esac

练习:写一个脚本showlogged.sh,其用法格式为:
showlogged.sh -v -c -h|--help
其中,-h选项只能单独使用,用于显示帮助信息;-c选项时,显示当前系统上登录的所有用户数;如果同时使用了-v选项,则既显示同时登录的用户数,又显示登录的用户的相关信息;如
Logged users: 4.

They are:
root tty2 Feb 18 02:41
root pts/1 Mar 8 08:36 (172.16.100.177)
root pts/5 Mar 8 07:56 (172.16.100.177)
hadoop pts/6 Mar 8 09:16 (172.16.100.177)

#!/bin/bash
#
declare -i SHOWNUM=
declare -i SHOWUSERS=
for I in `seq $#`; do
if [ $# -gt ]; then
case $ in
-h|--help)
echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"
exit ;;
-v|--verbose)
let SHOWUSERS=
shift ;;
-c|--count)
let SHOWNUM=
shift ;;
*)
echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"
exit ;;
esac
fi
done if [ $SHOWNUM -eq ]; then
echo "Logged users:`who | wc -l`"
if [ $SHOWUSERS -eq 1 ]; then
echo "They are:"
who
fi
fi
上一篇:Python 读写excel数据


下一篇:Java流程控制:增强for循环,break&continue,打印99乘法表