一、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为此条命令的输出状态码