for
循环是 Shell 脚本中最常用的循环结构之一,用于 遍历列表、处理文件、批量操作 等场景。
1. for
循环基础语法
1.1 基本格式
for 变量 in 列表
do
循环体命令
done
示例:
#序列1:
for i in 1 2 3
do
echo "数字: $i"
done
#序列2:
for i in {1..10}
do
echo "数字: $i"
done
#序列3:
for i in $(seq 10)
do
echo "数字: $i"
done
1.2 列表生成方式
方法 | 示例 | 说明 |
---|---|---|
直接列举 | for i in a b c | 遍历固定值 |
大括号扩展 | for i in {1..5} | 生成数字/字符序列 |
seq | for i in $(seq 100) | 生成数字序列 |
命令替换 | for file in $(ls) | 遍历命令输出 |
通配符匹配 | for file in *.txt | 遍历匹配的文件 |
数组遍历 | for item in "${array[@]}" | 遍历数组元素 |
2. 运维实战案例
案例 1:批量创建用户
版本一:
[root@lichu ~]# vim for_create_users1.sh
#!/bin/bash
# 用户名列表
users=("user1" "user2" "user3" "user4")
for user in "${users[@]}"
do
useradd "$user"
echo "用户 $user 创建成功!"
done
版本二:
[root@lichu ~]# vim for_create_users2.sh
#!/bin/bash
pass="123"
users=("yangge" "zhuzhuxia" "xuesong" "jack")
for user in "${users[@]}"
do
useradd "$user"
echo "$pass" |passwd --stdin $user &>/dev/null
echo "用户 $user 创建成功!"
done
案例 2:遍历文件并处理
[root@lichu ~]# vim for2.sh
#!/bin/bash
# 遍历当前目录所有 .log 文件
for logfile in *.log
do
echo "压缩文件: $logfile"
gzip "$logfile"
done
案例 3:批量 Ping 检测主机
版本一:
[root@lichu ~]# vim ping_hosts_check_for1.sh
#!/bin/bash
# 主机列表
hosts=("10.9.48.246" "10.9.48.247" "baidu.com")
for host in "${hosts[@]}"
do
if ping -c1 "$host" &>/dev/null; then
echo "$host 在线"
else
echo "$host 离线"
fi
done
echo "测试结束"
[root@lichu ~]# ./ping_hosts_check_for1.sh
10.9.48.246 在线
10.9.48.247 离线
baidu.com 在线
10.9.48.200 离线
使用绿色显示 [在线] echo -e "\e[32m [在线] \e[0m"
使用红色显示 [离线] echo -e "\e[31m [离线] \e[0m"
版本二:
[root@lichu ~]# vim ping_hosts_check_for2.sh
#!/bin/bash
for i in $(seq 254)
do
host="10.9.48.$i"
if ping -c1 $host &> /dev/null; then
echo -e "$host \e[32m [在线] \e[0m"
else
echo -e "$host \e[31m [离线] \e[0m"
fi
done
echo "测试结束"
版本三:
[root@lichu ~]# vim ping_hosts_check_for3.sh
#!/bin/bash
for i in $(seq 254)
do
{
host="10.9.48.$i"
if ping -c1 $host &> /dev/null; then
echo -e "$host \e[32m [在线] \e[0m"
else
echo -e "$host \e[31m [离线] \e[0m"
fi
}&
done
wait
echo "测试结束"
版本四:
[root@lichu ~]# vim ping_hosts_check_for4.sh
#!/bin/bash
>/tmp/hosts.txt
echo "正在Ping检测所有主机,请稍后..."
for i in $(seq 254)
do
{
host="10.9.48.$i"
if ping -c1 $host &> /dev/null; then
echo "$host" >> /tmp/hosts.txt
fi
}&
done
wait
echo "测试结束,请查看文件/tmp/hosts.txt"
案例 4:数字循环(C 语言风格)
#!/bin/bash
# 从 1 循环到 10,步长 1
for ((i=1; i<=10; i++)) # 初始值i=1; 条件判断i<=10; 步长i++
do
echo "当前值: $i"
done
#!/bin/bash
# 从 1 循环到 10,步长 2
for ((i=1; i<=10; i+=2))
do
echo "当前值: $i"
done
i++ 等价于 i=i+1
i+=2 等价于 i=i+2
i-=2 等价于 i=i-2
案例 5:读取文件内容逐行处理
版本一:
#!/bin/bash
# 逐行读取文件
for line in $(cat /etc/hosts)
do
echo "行内容: $line"
done
版本二:
#!/bin/bash
# 字段分隔符(IFS)默认值:空格、制表符(\t)、换行符(\n)
IFS=$'\n'
for line in $(cat /etc/hosts)
do
echo "行内容: $line"
done
补充知识:
[root@lichu ~]# vim yangge.txt
yang,ge,lichu
[root@lichu ~]# vim for3.sh
#!/bin/bash
for i in $(cat yangge.txt)
do
echo "内容: $i"
done
内容: yang,ge,lichu
[root@lichu ~]# vim for4.sh
#!/bin/bash
IFS=','
for i in $(cat yangge.txt)
do
echo "内容: $i"
done
3. 高级用法
3.1 嵌套循环
在50台服务器上,分别创建10个用户
for i in {1..3}
do
for j in A B
do
echo "组合: $i$j"
done
done
echo "结束......."
3.2 跳过某次循环(continue
)
for i in {1..10}
do
if [ "$i" -eq 5 ]; then
continue # 跳过本次循环
fi
echo "当前值: $i"
done
echo "结束......."
3.3 提前终止循环(break
)
for i in {1..10}
do
if [ "$i" -eq 5 ]; then
break # 跳出循环(默认为一层)
fi
echo "当前值: $i"
done
echo "结束......."