for和while之间的区别
for和while之间的区别
行读取的区别
#!/bin/bash
df -hl |awk 'int($5) >30' > df.txt
result=$(df -hl |awk 'int($5) >30')
echo "-------------- for遍历变量 ---------------------"
for i in $result
do
echo $i
done
echo "--------------- while 遍历遍量 ------------------------------"
echo $result |while read line
do
echo $line
done
echo "-------------- for 遍历文件 --------------------"
line=$(cat ./df.txt)
for i in line
do
echo $line
done
echo "-------------- while 遍历文件 -------------------"
while read line
do
echo $line
done <df.txt
执行上面的脚本
得出的结果为:
-
while循环: 以行读取文件,默认分隔符是空格或者Tab;
-
for循环: 以空格读取文件,也就是碰到空格,就开始执行循环体,所以需要以行读取的话,就要把空格转换成其他字符。
while循环遍历文件
for循环遍历变量
不同场景使用不同的循环
通过文件创建用户的脚本
假设文件是ip.txt
maomao 123
zhuzhu 456
niuniu 789
如果文件中有空行使用for就需要自定义分隔符
#!/bin/bash
#v1.0 by stanZ 2020-12-15
if [ $# -eq 0 ];then
echo "usage:`basename $0` file"
exit 1
fi
if [ ! -f $1 ];then
echo "error file"
exit 2
fi
#希望for处理文件按回车分隔,而不是空格或者tab空格
#重新定义分隔符
#IFS内部字段分隔符
#IFS=$'\n'
IFS='
'
for line in `cat $1`
do
user=`echo "$line" |awk '{print $1}'`
passwd=`echo "$line" |awk '{print $2}'`
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "user $user already exists"
else
useradd $user
echo "$passwd" |passwd --stdin $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is created"
fi
fi
done
使用while
#!/bin/bash
#while create user
#v1.0 by stanZ 2020-12-17
if [ $# -eq 0 ];then
echo "usage:`basename $0` file"
exit 10
fi
if [ ! -f $1 ];then
echo "error file"
exit 5
fi
while read line
do
user=`echo $line |awk '{print $1}'`
pass=`echo $line |awk '{print $2}'`
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user already exists"
else
useradd $user
echo "$pass" |passwd --stdin $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is created."
fi
fi
done < $1
综上所述 while在处理文件比for方便
统计系统里各种状态的脚本
统计/etc/passwd里面shells的各种状态数量
#!/bin/bash
# 首先使用for
declare -A shells
shell=`cat /etc/passwd |awk -F: '{print $NF}'`
for i in $shell
do
let shells[$i]++
done
for i in ${!shells[*]}
do
echo "$i:${shells[$i]}"
done
# 执行脚本
[root@maomao 1.11]# bash shells1.sh
/sbin/nologin:25
/bin/sync:1
/bin/bash:12
/sbin/shutdown:1
/sbin/halt:1
#!/bin/bash
# 使用while
declare -A shells
while read line
do
shell=`echo $line |awk -F: '{print $NF}'`
let shells[$shell]++
done </etc/passwd
for i in ${!shells[*]}
do
echo "$i:${shells[$i]}"
done
# 执行脚本
[root@maomao 1.11]# bash shells1.sh
/sbin/nologin:25
/bin/sync:1
/bin/bash:12
/sbin/shutdown:1
/sbin/halt:1
统计TCP连接状态数量
#!/bin/bash
# count tcp status
# by stanZ 1.3
while :
do
unset status # 取消一次变量 不然数值会重叠
declare -A status
type=$(ss -an|grep :80 |awk '{print $2}')
for i in $type
do
let status[$i]++
done
for j in ${!status[@]}
do
echo "$j:${status[$j]}"
done
sleep 1
clear
done