Linux shell while 循环以及各种括号的应用
touch file{1..3}.txt# 创建 file1.txt, file2.txt, file3.txt。echo ${VAR:=default}# 如果VAR未设置,设置VAR为default。echo {A,B,C}{1,2}# 输出: A1 A2 B1 B2 C1 C2。当存在多个语句是需要大括号,{}&+ wait组合 表示后台处理,并且是并发的处理。echo ${VAR:-def
1:while 循环和 until 循环
while 循环是用来重复执行一组命令或语句常用与守护进程或者持续运行的程序
可以是次数固定的,也可以是不固定的
语法
while 条件测试
do
循环体内部逻辑
done
until 和 while 相反,到达某个条件不成立时,进入循环体执行指令,表达式成立时,跳出循环
语法
until 条件测试
do
循环体
done
while 代码案例
[root@hadoop ~]# cat while_create_user.sh
#! /bin/bash
while read line
do
if [ ${#line} -eq 0 ];then
echo "---------------------------"
continue
fi
user=`echo $line | awk '{print $1}'`
pass=`echo $line | awk '{print $2}'`
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is already exists"
else
useradd $user
echo "$pass" | passwd --stdin "$user" &>/dev/null
if [ $? -eq 0 ];then
echo "$user create success...."
fi
fi
done < user2.txt
chmod +x while_create_user.sh
在user2.txt中添加
liyifei 000
yangmi 111
cangjinkong 222
jizemingbu 333
user add cangjingkong
user add jizemingbu
./while_create_user.sh 执行结果如下
[root@hadoop ~]# ./while_create_user.sh
useradd:警告:此主目录已经存在。
不从 skel 目录里向其中复制任何文件。
正在创建信箱文件: 文件已存在
liyifei create success....
useradd:警告:此主目录已经存在。
不从 skel 目录里向其中复制任何文件。
正在创建信箱文件: 文件已存在
yangmi create success....
cangjinkong is already exists
jizemingbu is already exists
另一种方式
#!/bin/bash
while read line
do
# 跳过空行
if [ ${#line} -eq 0 ]; then
echo "---------------------------"
continue
fi
#这里使用$()的方式来替代 `` 反引号
user=$(echo "$line" | awk '{print $1}')
pass=$(echo "$line" | awk '{print $2}')
id "$user" &>/dev/null
if [ $? -eq 0 ]; then
echo "$user is already exists"
else
useradd "$user"
# 使用chpasswd来设置密码(更可靠的方法)
echo "${user}:${pass}" | chpasswd
if [ $? -eq 0 ]; then
echo "$user create success...."
else
echo "Failed to set password for $user"
fi
fi
done < user2.txt
将判断语句缩写一下
#!/bin/bash
while read line
do
if [ ${#line} -eq 0 ]; then
echo "---------------------------"
continue
fi
user=$(echo "$line" | awk '{print $1}')
pass=$(echo "$line" | awk '{print $2}')
if id "$user" &>/dev/null; then
echo "$user already exists"
else
if useradd "$user"; then
if echo "$pass" | passwd --stdin "$user" &>/dev/null; then
echo "$user create success...."
else
echo "Failed to set password for $user"
# 可以考虑删除创建的用户
userdel "$user"
fi
else
echo "Failed to create user $user"
fi
fi
done < user2.txt
案例2 : while 循环探测远程主机是否在线
方案1:监控 IP 下线(当前逻辑)
#!/bin/bash
ip=192.168.88.103
while ping -c1 -W1 $ip &>/dev/null
do
sleep 1
done
echo "$ip is down"
方案2:等待 IP 上线
#!/bin/bash
ip=192.168.88.103
while ! ping -c1 -W1 $ip &>/dev/null
do
sleep 1
done
echo "$ip is up"
方案3:增强版本(带状态显示)
#!/bin/bash
ip=192.168.88.103
echo "Monitoring $ip..."
while true
do
if ping -c1 -W1 $ip &>/dev/null; then
echo "$(date): $ip is up"
else
echo "$(date): $ip is down"
fi
sleep 1
done
方案4:超时控制版本
#!/bin/bash
ip=192.168.88.103
timeout=60
count=0
echo "Waiting for $ip to come online (timeout: ${timeout}s)..."
while [ $count -lt $timeout ]
do
if ping -c1 -W1 $ip &>/dev/null; then
echo "$ip is now online!"
exit 0 #正常退出
fi
sleep 1 #默认是秒
count=$((count + 1))
done
echo "Timeout: $ip did not come online within ${timeout} seconds"
exit 1 #异常退出
until 循环的案例
[root@hadoop ~]# vim until_ping.sh
#! /bin/bash
ip=192.168.88.103
until ping -c1 -W1 $ip &>/dev/null
do
sleep 1
done
echo "$ip is up"
[root@hadoop ~]# cat until_ping.sh
[root@hadoop ~]# chmod +x until_ping.sh
[root@hadoop ~]# ./until_ping.sh
192.168.88.103 is up
do 和 done 之间只有一个语句的时候可以省略{}
do
sleep 1
done
当存在多个语句是需要大括号,{}& + wait组合 表示后台处理,并且是并发的处理
do
{}
done
for 循环实现并发控制案例
1:非并发的情况
[root@hadoop ~]# cat noparell.sh
#! /bin/bash
start=`date +%s`
for ((i=1;i<=1000;i++))
do
sleep 1
echo "$i success"
done
end=`date +%s`
echo "cost time: `$end-$start`"
执行结果,每秒执行一次,需要同步等待到循环全部执行完成再打印消费的时间
并发的写法
[root@hadoop ~]# cat parell.sh
#!/bin/bash
start=`date +%s`
for ((i=1;i<=1000;i++))
do
{
sleep 1
echo "$i success"
}&
done
wait
end=`date +%s`
cost=$((end - start))
echo "cost time is: $cost"
执行结果
991 success
993 success
1000 success
995 success
994 success
988 success
984 success
990 success
cost time is: 2
用{} 括起来 后面加一个& 表示每次都将命令放到后台运行
循环1000次就会有1000个& 把任务放到后台,操作系统会并发1000个线程来执行这些任务
wait 命令等待上一个命令执行完了再执行,一条命令一旦交给后台,shell就会往下执行
只要遇到 & 就会将任务交给后台,具体什么时候执行,有操作系统的cpu自行分配时间片
执行顺序是无序的
==============================================================
linux 管道实现shell 的并发控制 todo (需要补充管道的知识)
==============================================================
linux 中 (()) [] {} 的用途
在 Linux Shell 中,(())、[]、{} 是三种不同的语法结构,各有特定的用途:
1. (()) - 算术运算
用途:整数算术计算
# 基本算术运算
a=5
b=3
echo $((a + b)) # 输出: 8
echo $((a * b)) # 输出: 15
echo $((a % b)) # 输出: 2
# 自增自减
((a++)) # a=6
((b--)) # b=2
# 复合运算
((a += 5)) # a=11
((b *= 3)) # b=6
在条件判断中
if ((a > b)); then
echo "a is greater than b"
fi
for ((i=0; i<5; i++)); do
echo "i = $i"
done
2. [] 或 test 命令
用途:条件测试
# 文件测试
if [ -f "/etc/passwd" ]; then
echo "File exists"
fi
if [ -d "/tmp" ]; then
echo "Directory exists"
fi
# 字符串比较
name="John"
if [ "$name" = "John" ]; then
echo "Hello John"
fi
if [ -n "$name" ]; then
echo "Name is not empty"
fi
# 数值比较
a=10
b=20
if [ $a -lt $b ]; then
echo "a is less than b"
fi
常用测试运算符:
bash
# 文件测试
[ -f file ] # 文件存在且是普通文件
[ -d dir ] # 目录存在
[ -r file ] # 文件可读
[ -w file ] # 文件可写
[ -x file ] # 文件可执行
# 字符串测试
[ -z str ] # 字符串为空
[ -n str ] # 字符串非空
[ str1 = str2 ] # 字符串相等
[ str1 != str2 ] # 字符串不等
# 数值比较
[ a -eq b ] # 等于
[ a -ne b ] # 不等于
[ a -lt b ] # 小于
[ a -le b ] # 小于等于
[ a -gt b ] # 大于
[ a -ge b ] # 大于等于
3. {} - 代码块和扩展
用途1:代码块(命令分组)
# 在当前shell执行(影响当前环境)
{
cd /tmp
ls -l
pwd
}
# 在子shell执行(不影响当前环境)
(
cd /tmp
ls -l
pwd
)
echo "Back to: $(pwd)" # 仍然在原始目录
用途2:大括号扩展
# 生成序列
echo {1..5} # 输出: 1 2 3 4 5
echo {a..e} # 输出: a b c d e
echo {01..10} # 输出: 01 02 03 ... 10
# 组合扩展
echo {A,B,C}{1,2} # 输出: A1 A2 B1 B2 C1 C2
# 文件操作
touch file{1..3}.txt # 创建 file1.txt, file2.txt, file3.txt
mkdir {bin,lib,src} # 创建三个目录
用途3:变量操作
name="filename"
echo ${name} # 基本变量引用
echo ${name%.*} # 去除后缀: filename
echo ${name#*.} # 去除前缀(如果有后缀)
# 默认值设置
echo ${VAR:-default} # 如果VAR未设置,使用default
echo ${VAR:=default} # 如果VAR未设置,设置VAR为default
综合比较示例
#!/bin/bash
# (()) 用于算术
a=10
b=5
((result = a + b))
echo "Arithmetic: $result"
# [] 用于条件测试
if [ $a -gt $b ]; then
echo "Condition: a > b"
fi
# {} 用于代码块和扩展
{
echo "Block: Starting task"
sleep 1
echo "Block: Task completed"
}
# 大括号扩展
echo "Expansion: "{1..3}
记忆技巧
(()):算术运算(Arithmetic)
[]:条件测试(Condition/Test)
{}:代码块和扩展(Block/Expansion)
现代替代语法
[[]]:增强版条件测试(推荐)
(()):算术运算
$():命令替换(替代反引号)``
# 推荐使用 [[]] 代替 []
if [[ $name == "John" && $age -gt 18 ]]; then
echo "Welcome John"
fi
这三种语法结构是 Shell 编程的基础,熟练掌握它们对于编写高效的脚本非常重要
更多推荐

所有评论(0)