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,则显示最后一个磁盘上的空间使用信息
1 #! /bin/bash 2 # 3 diskcount=`fdisk -l | grep "^磁盘 /dev/[sh]d[a-z]" | wc -l` 4 lastdisk=`fdisk -l | grep -o "^磁盘 /dev/[sh]d[a-z]|tail -1 | cut -d' ' -f2"` 5 if [ $diskcount -eq 1 ];then 6 fdisk -l /dev/[hs]d[a-z]; 7 elif [ $diskcount -gt 1 ];then 8 fdisk -l $lastdisk 9 fi
2. 添加10个用户,密码同用户名
#! /bin/bash # for i in {1..10};do if id user$i &> /dev/null;then echo "用户已存在" else useradd user$i if [ $? -eq 0 ];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 1 1 9);do for j in $(seq 1 1 $i);do echo -n -e "$j*$i=$[$i*$j] " done echo -e " " done
5. 通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态
#!/bin/bash iptmp="192.168.1" uphosts=0 downhosts=0 for i in $(seq 1 1 254); do ping -c 1 -w 1 $iptmp.$i &> /dev/null if [ $? -eq 0 ]; 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=1 declare -i sum=0 while [ $i -le 100 ];do let sum+=$i let i++ done echo "1到100整数和为$sum"
2.添加10个用户
#!/bin/bash declare -i i=1 while [ $i -le 10 ];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.1 declare -i i=1 uphosts=0 downhosts=0 while [ $i -le 254 ];do if ping -c 1 -w 1 $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=1 declare -i j=1 while [ $i -le 9 ];do while [ $j -le $i ];do echo -n -e "$j*$i=$[$i*$j] " let j++ done echo -e " " let i++ let j=1 done
4.利用RANDOM生成10个随机数字,输出其中最大值和最小值
#!/bin/bash declare -i i=1 declare -i max=0 declare -i min=0 declare -i temp=0 while [ $i -le 10 ]; 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=0 declare -i sum=0 until [ $i -gt 100 ];do let i++ let sum+=$i done echo "sum为$sum"
2. 打印九九乘法表(until实现)
#!/bin/bash declare -i i=1 declare -i j=1 until [ $i -gt 9 ];do until [ $j -gt $i ];do echo -n -e "$j*$i=$[$i*$j] " let j++ done echo -e " " let i++ let j=0 done
循环控制语句(break,continue)
1. 求100以内所有偶数之和
#!/bin/bash declare -i i=0 declare -i sum=0 until [ $i -gt 100 ];do let i++ if [ $[$i%2] -eq 1 ];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 3 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%2] -eq 0 ];then username=`echo $line | cut -d: -f1` echo "用户名为$username,ID号为$ids" fi done < $file
for循环的特殊格式
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式));do
done
示例: 求100以内所有正整数之和
#!/bin/bash declare -i sum=0 for ((i=1;i<=100;i++));do let sum+=$i done echo "sum的值为$sum"
2. 打印九九乘法表
#!/bin/bash for((i=1;i<=9;i++));do for((j=1;j<=$i;j++));do echo -n -e "$j*$i=$[$i*$j] " done echo -e " " 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 0 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 0 ;; 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 $0` 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 1 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=0 declare -i SHOWUSERS=0 for I in `seq 1 $#`; do if [ $# -gt 0 ]; then case $1 in -h|--help) echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose" exit 0 ;; -v|--verbose) let SHOWUSERS=1 shift ;; -c|--count) let SHOWNUM=1 shift ;; *) echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose" exit 8 ;; esac fi done if [ $SHOWNUM -eq 1 ]; then echo "Logged users:`who | wc -l`" if [ $SHOWUSERS -eq 1 ]; then echo "They are:" who fi fi