一、for循环定义:

        将一段代码反复执行;----->进入条件;------> 退出条件;


二、语法格式:

for 变量名 in LIST

do 

statement1

...

done


for VAR in LIST; do statement1; statement2; ...; done


三、LIST:列表

定义:包含至少一个元素的字符串集合;

LIST的生成方法:

(1) 直接给出;

(2) 数值列表:

(a) {start..end},例如:{1..10}

(b) seq [start [step]] end

(3) 返回列表的命令;

(4) globbing;

(5) 变量引用;

$*, $@


例如:添加3个用户,user1, user2, user3; 密码同用户名;

# vim user.sh
#!/bin/bash
#
for username in user1 user2 user3 ; do
       useradd $username
       echo $username |passwd --stdin $username
done
# bash -n user.sh 
# bash -x user.sh


例如:添加9个用户,user101...user109;密码同用户名;

#!/bin/bash
#
useradd user10$n
for n in {1..9}; do
    echo user10$n | passwd --stdin user10$n &>/dev/null   
done
        &>/dev/null 省略报告是否创建成功失败信息


四、for循环练习题:

练习1:于/tmp/test目录中创建10个空文件f1,.., f10;

#!/bin/bash
#
for n in {1..10}; do
      mkdir /tmp/test/file$n &>/dev/null
done


练习2:写一个脚本,

(1) 创建"/tmp/test-当前时间"目录;

(2) 添加10用户tuser1,.., tuser10; 

(3) 在"/tmp/test-当前时间"目录中,创建10空文件f1,...,f10;

(4) 修改f1的属主为tuser1;依次类推;

#!/bin/bash
#
directory=/tmp/test-`date +%H-%N-%S`
mkdir $directory
for i in {1..10};do 
useradd tuser$i
touch $directory/f$i
chown tuser$i $directory/f$i
done


练习3:求100以内所有正整数之和;

#!/bin/bash
#
sum=0
#
for n in {1..100}; do
    sum=$[$n+$sum]
done
            注意:sum=0也可表示为declare -i sum=0
            let sum+=$i 也表示sum自身与&i相加


练习4:求100以内所有偶数之和;以及所有奇数之和;

#!/bin/bash
#
ODD_SUM=0
#
EVEN_SUM=0
#
ODD_LIST=$(seq 1 2 100)
EVEN_LIST=$(seq 0 2 100)
#
for n in $ODD_LIST; do
    ODD_SUM=$[$ODD_SUM+$n]
done
#
echo "一到一百的奇数和为:$ODD_SUM"
#
for m in $EVEN_LIST; do
    EVEN_SUM=$[$EVEN_SUM+$m]
done
#
echo "一到一百的偶数和为:$EVEN_SUM"



练习5:计算当前系统上所有用户ID之和;

#!/bin/bash
#
UID_SUM=0
UID_LIST=$(cut -d':' -f3 /etc/passwd)
#
for n in $UID_LIST; do
    UID_SUM=$[$UID_SUM+$n]
done
echo "The all user ID sum is '$UID_SUM'"


练习6:传递参数(文本文件路径)给脚本,统计所有文件的空白行数之和;显示此次共对多少文件进行统计;

#!/bin/bash
#
File_Sum=$#
echo "the sum of file is $File_Sum"
for i in $*; do
    Space_Sum=$(grep '^[[:space:]]*$' $i | wc -l)
    SPACE_ALL=$[$SPACE_ALL+$Space_Sum]
done
echo "the sum of space is $SPACE_ALL"
#  $*可以直接生成文件列表


练习7:显示当前系统所有默认shell为bash的用户的总数;并统计此些用户ID之和;

#!/bin/bash
#
BASH_SUM=0
BASH_SUM=$(grep 'bash$' /etc/passwd | wc -l)
echo "the sum of bash is $BASH_SUM"
UID_SUM=0
UID_LIST=$(grep 'bash$' /etc/passwd | cut -d':' -f3)
for n in $UID_LIST; do
    UID_SUM=$[$UID_SUM+$n]
done
echo "the sum of BID is $UID_SUM"
grep 'bash$' /etc/passwd | cut -d':' -f3



练习8:写一个脚本

(1) 假设某目录下分别有K##和S##开头文件若干;(/etc/rc.d/rc3.d/为例;)

(2) 给此目录下的所有以K开头的文件,传递一个stop参数;(echo "/etc/rc.d/rc3.d/atd stop")

(3) 给此目录下的所有以S开头的文件,传递一个start参数;

#!/bin/bash
for file in /etc/rc.d/rc3.d/K*; do
         echo '$file stop'   another way: echo -e "$file stop...........[\033[34mOK\033[0m]" 则后面会显示蓝色OK
done
for file in /etc/rc.d/rc3.d/S*; do
         echo '$file start'
done




练习9:写一个脚本

(1) 使用Ping命令探测172.16.100.X主机的在线状态;

#!/bin/bash
             for host in {1..254}; do
    ping -c1 -w1 172.16.100.$host
done


练习10:写一个脚本

(1) 给一个脚本传递一些用户名;

(2) 计算此些用户所属基本组的id之和;

#!/bin/bash
            declare -i GSUM=0
for username in $1; do
    GSUM=$[$GSUM+`id -g $username`]
done
echo the GID_SUM is $GSUM



五、for的几种特殊情况:

(1) for省略,会自动获取脚本参数列表;

(2) C编程风格:

for ((变量赋值;循环条件;修正表达式)); do

CMD1

CMD2

done

例如:求100以内偶数之和

#!/bin/bash
declare -i evensum=0
for ((i=2;i<=100;i+=2));do
let evensum+=$i
done
echo $evensum


(3) 循环嵌套:

for i in [LIST1]; do

CMD1

for j in [LIST2]; do

CMD2

...

done

done


练习11:写一个脚本

(1) ping 172.16.X.Y内的所有主机;

172.16.0-255.1-254

#!/bin/bash
for i in {0..255}; do
    for j in {1..254}; do
        ping -c1 -w1 172.16.$i.$j
    done
done


练习12:写个脚本

(1) 传递一些目录给脚本;

(2) 逐个显示每个目录下的所有一级文件的内容类型;

(3) 统计一个有多少个目录;一共显示了多少个文件;

#!/bin/bash
#
declare -i dirs=0
declare -i files=0
for d in $*; do
    for f in $d/*; do
        file $f
        let files++
    done
    let dirs++
done
echo "Directories: $dirs."
echo "Files: $files."
        解析:let dirs++ 为计数器,就是循环多少次,计数为多少;等价于dir=[$dirs+1]


六、bash命令退出和退出状态码

命令在bash中执行结束退出时,其执行成功与否可通过退出状态码来记录;


脚本的退出状态码取决于执行的最后一条命令;自定义退出状态码:

exit #


成功:0

失败:1-255


注意:提前退出脚本,也可使用exit命令实现;

例如:以某条命令的状态作为脚本的退出状态码

#!/bin/bash
#
ls /varr
retval=$?
echo "hello"
exit $retval
解析:retval为此条命令的输出状态码