循环:for, while, until
循环体:要执行的代码;可能要执行n遍;
进入条件:
退出条件:
for循环:
for 变量名 in 列表; do
循环体
done
执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束;
示例:添加10个用户, user1-user10;密码同用户名;
#!/bin/bash
#
if [ ! $UID -eq 0 ]; then
echo "Only root."
exit 1
fi
for i in {1..10}; do
if id user$i &> /dev/null; then
echo "user$i exists."
else
useradd user$i
if [ $? -eq 0 ]; then
echo "user$i" | passwd --stdin user$i &> /dev/null
echo "Add user$i finished."
fi
fi
done
列表生成方式:
(1) 直接给出列表;
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令;
$(COMMAND)
(4) glob
(b) 变量引用;
$@, $*
示例:判断某路径下所有文件的类型
#!/bin/bash
#
for file in $(ls /var); do
if [ -f /var/$file ]; then
echo "Common file."
elif [ -L /var/$file ]; then
echo "Symbolic file."
elif [ -d /var/$file ]; then
echo "Directory."
else
echo "Other type."
fi
done
示例:
#!/bin/bash
#
declare -i estab=0
declare -i listen=0
declare -i other=0
for state in $( netstat -tan | grep "^tcp\>" | awk '{print $NF}'); do
if [ "$state" == 'ESTABLISHED' ]; then
let estab++
elif [ "$state" == 'LISTEN' ]; then
let listen++
else
let other++
fi
done
echo "ESTABLISHED: $estab"
echo "LISTEN: $listen"
echo "Unkown: $other"
练习1:/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;
分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;
“K34filename stop”
“S66filename start”
练习2:写一个脚本,使用ping命令探测172.16.250.1-254之间的主机的在线状态;
for循环语法:
for NAME in LIST; do
循环体
done
列表生成方式:
(1) 整数列表
{start..end}
$(seq start [[step]end])
(2) glob
/etc/rc.d/rc3.d/K*
(3) 命令
通过ping命令探测10.49.128.1-254范围内的所有主机的在线状态;
#!/bin/bash
#
net='10.49.128'
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."
while循环:
while CONDITION; do
循环体
循环控制变量修正表达式
done
进入条件:CONDTION测试为"真"
退出条件:CONDTION测试为"假"
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正;
until循环:
until CONDITION; do
循环体
循环控制变量修正表达式
done
进入条件:CONDTION测试为"假"
退出条件:CONDTION测试为"真"
示例:求100以内所有正整数之和;
#!/bin/bash
#
declare -i sum=0
declare -i i=1
while [ $i -le 100 ]; do
let sum+=$i
let i++
done
echo "$i"
echo "Summary: $sum."
练习:添加10个用户
user1-user10
#!/bin/bash
#
declare -i i=1
declare -i users=0
while [ $i -le 10 ]; do
if ! id user$i &> /dev/null; then
useradd user$i
echo "Add user: user$i."
let users++
fi
let i++
done
echo "Add $users users."
练习:通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态;(用while循环)
#!/bin/bash
#
declare -i i=1
declare -i uphosts=0
declare -i downhosts=0
net='172.16.250'
while [ $i -le 20 ]; do
if ping -c 1 -w 1 $net.$i &> /dev/null; then
echo "$net.$i is up."
let uphosts++
else
echo "$net.$i is down."
let downhosts++
fi
let i++
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 -e -n "${i}X${j}=$[$i*$j]\t"
done
echo
done
#!/bin/bash
#
declare -i i=1
declare -i j=1
while [ $j -le 9 ]; do
while [ $i -le $j ]; do
echo -e -n "${i}X${j}=$[$i*$j]\t"
let i++
done
echo
let i=1
let j++
done
练习:利用RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者;
#!/bin/bash
#
declare -i max=0
declare -i min=0
declare -i i=1
while [ $i -le 9 ]; do
rand=$RANDOM
echo $rand
if [ $i -eq 1 ]; then
max=$rand
min=$rand
fi
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脚本编程
while CONDITION; do
循环体
done
进入条件:CONDITION为true;
退出条件:false
until CONDITION; do
循环体
done
进入条件:false
退出条件:true
示例:求100以内所正整数之和;
#!/bin/bash
#
declare -i i=1
declare -i sum=0
until [ $i -gt 100 ]; do
let sum+=$i
let i++
done
echo "Sum: $sum"
示例:打印九九乘法表
#!/bin/bash
#
declare -i j=1
declare -i i=1
until [ $j -gt 9 ]; do
until [ $i -gt $j ]; do
echo -n -e "${i}X${j}=$[$i*$j]\t"
let i++
done
echo
let i=1
let j++
done
循环控制语句(用于循环体中):
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done
break [N]:提前结束循环;
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
示例1:求100以内所有偶数之和;要求循环遍历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 "Even sum: $sum"
创建死循环:
while true; do
循环体
done
until false; do
循环体
done
示例2:每隔3秒钟到系统上获取已经登录的用户的信息;如果docker登录了,则记录于日志中,并退出;
#!/bin/bash
#
read -p "Enter a user name: " username
while true; do
if who | grep "^$username" &> /dev/null; then
break
fi
sleep 3
done
echo "$username logged on." >> /tmp/user.log
第二种实现:
#!/bin/bash
#
read -p "Enter a user name: " username
until who | grep "^$username" &> /dev/null; do
sleep 3
done
echo "$username logged on." >> /tmp/user.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
let sum+=$i
done
echo "Sum: $sum."
示例2:打印九九乘法表;
#!/bin/bash
#
for((j=1;j<=9;j++));do
for((i=1;i<=j;i++))do
echo -e -n "${i}X${j}=$[$i*$j]\t"
done
echo
done