20260413 if while 语句

一、IF 语句

1.1 语法

1.1.1 单分支语法

bash 复制代码
# 单分支
if 条件判断;then
  command
fi

if 条件判断
then
  command
fi

条件判断 && command

1.1.2 双分支语法

bash 复制代码
# 单分支
if 条件判断;then
  command1
else
  command2
fi

条件判断 && command1 || command2

1.1.3 多分支语法

bash 复制代码
# 单分支
if 条件1判断;then
  command1
elif 条件2判断;then
  command2
else
  command3
fi

1.2 实践

示例1:单分支

需求:如果sshd服务正常运行,则提示服务正在运行。

开发脚本if_sshd_1.sh ,内容如下:

bash 复制代码
[root@centos7 bin 13:53:41]# vim if_ssh_1.sh

#!/bin/bash
status="$(systemctl is-active sshd)"
if [ "$status" == "active" ];then
  echo sshd is running.
fi

# 或者

#!/bin/bash
systemctl is-active sshd &>/dev/null
if (($?==0));then
  echo sshd is running.
fi

运行结果:

bash 复制代码
[root@centos7 bin 13:46:42]# systemctl start sshd
[root@centos7 bin 13:46:46]# bash if_sshd_1.sh 
sshd is running.

示例2:双分支

需求:

  • 如果sshd服务正常运行,则提示服务正在运行
  • 提示服务未运行,并启动服务,启动后提示服务正常运行。

开发脚本if_sshd_2.sh ,内容如下:

bash 复制代码
[root@centos7 bin 13:43:41]# vim if_ssh_2.sh

#!/bin/bash
status="$(systemctl is-active sshd)"
if [ "$status" == "active" ];then
  echo sshd is running.
else
  systemctl start sshd && echo "Start sshd success."
fi

运行结果:

bash 复制代码
[root@centos7 bin 13:44:04]# systemctl stop sshd
[root@centos7 bin 13:44:57]# bash if_sshd_2.sh 
Start sshd success.
[root@centos7 bin 13:45:01]# bash if_sshd_2.sh 
sshd is running.

示例3:多分支

需求:开发if_sshd_3.ctl脚本。

  • 脚本使用方法:"Usage:$0 start|stop|status|restart|reload"
  • 如果参数数量个数不是1个,则输出脚本使用方法。
  • 如果$1是start,则执行'systemctl start sshd'
  • 如果$1是stop,则执行'systemctl stop sshd'
  • 如果$1是status,则执行'systemctl status sshd'
  • 如果$1是restart,则执行'systemctl restart sshd'
  • 如果$1是reload,则执行'systemctl reload sshd'

如果$1是其他子命令,则输出脚本使用方法。

bash 复制代码
[root@centos7 ~ 14:20:32]# vim if_sshd_3.ctl

#!/bin/bash

service_name=sshd

if (($#!=1));then
  echo "Usage:$0 start|stop|status|restart|reload"
  exit
fi

if [ "$1" == "start" ];then
  systemctl start ${service_name}
elif [ "$1" == "stop" ];then
  systemctl stop ${service_name}
elif [ "$1" == "status" ];then
  systemctl status ${service_name}
elif [ "$1" == "restart" ];then
  systemctl restart ${service_name}
elif [ "$1" == "reload" ];then
  systemctl reload ${service_name}
else
  echo "Usage:$0 start|stop|status|restart|reload"
fi

运行结果:

bash 复制代码
[root@centos7 ~ 14:16:15]# chmod +x if_sshd_3.ctl

# 缺乏参数
[root@centos7 ~ 14:22:41]# if_sshd_3.ctl 
Usage: /root/bin/if_sshd_3.ctl start|stop|status|restart|reload

# 只能传递1个参数
[root@centos7 bin 14:24:32]# if_sshd_3.ctl stop
Usage:/root/bin/if_sshd_3.sh start|stop|status|restart|reload

# 传递正常参数
[root@centos7 bin 14:53:46]# if_sshd_3.ctl status
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2026-04-13 14:53:46 CST; 1s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 11882 (sshd)
   CGroup: /system.slice/sshd.service
           └─11882 /usr/sbin/sshd -D

Apr 13 14:53:46 centos7.jqz.cloud systemd[1]: Starting OpenSSH server daemon...
Apr 13 14:53:46 centos7.jqz.cloud sshd[11882]: Server listening on 0.0.0.0 port 22.
Apr 13 14:53:46 centos7.jqz.cloud sshd[11882]: Server listening on :: port 22.
Apr 13 14:53:46 centos7.jqz.cloud systemd[1]: Started OpenSSH server daemon.

# 传递不存在的参数
[root@centos7 bin 14:55:30]# if_sshd_3.sh addvssvd
Usage:/root/bin/if_sshd_3.sh start|stop|status|restart|reload

优化后脚本-不带注释

bash 复制代码
#!/bin/bash

service_name=sshd
action="$1"

if (($#!=1));then
  echo "Usage:$0 start|stop|status|restart|reload $2"
  exit
fi

if [ "$1" == "start" -o "$1" == "stop" -o "$1" == "status"  -o "$1" == "restart" -o "$1" == "reload" ];then
  systemctl $action ${service_name}
else
  echo "Usage:$0 start|stop|status|restart|reload"
fi

优化后脚本-带注释

bash 复制代码
#!/bin/bash
# 功能:一键管理 sshd 服务的启动/停止/重启/状态查看
# 用法:./脚本名 start|stop|status|restart|reload

# 定义要管理的服务名称为 sshd(远程登录服务)
service_name=sshd

# 接收用户输入的第一个参数(动作:start/stop/restart等)
action="$1"

# ==============================================
# 判断参数个数:如果参数数量不等于1,就提示用法并退出
# $# 表示脚本接收的参数个数
# ==============================================
if (($#!=1));then
  # 输出正确用法提示
  echo "Usage:$0 start|stop|status|restart|reload $2"
  # 退出脚本
  exit
fi

# ==============================================
# 判断用户输入的参数是否合法
# 支持:start | stop | status | restart | reload
# ==============================================
if [ "$1" == "start" -o "$1" == "stop" -o "$1" == "status"  -o "$1" == "restart" -o "$1" == "reload" ];then
  # 如果参数合法,执行 systemctl 命令管理服务
  systemctl $action ${service_name}
else
  # 如果参数不合法,提示正确用法
  echo "Usage:$0 start|stop|status|restart|reload"
fi

二、FOR语句

2.1 语法

2.1.1 shell自带语法

bash 复制代码
for 变量名 in 清单
do
  command
done

2.2.2 C语言格式语法

bash 复制代码
for ((num=1;num<=10;num++))
do
  echo $num
done

# 执行效果如下
1
2
3
4
5
6
7
8
9
10

2.2 实践

2.2.2 示例1:计算1+2+...+9+10的和

bash 复制代码
[root@centos7 bin 15:18:22]# cat for1.sh 
#!/bin/bash
sum=0
for num in {1..10}
do
  sum=$[ sum+num ]
done
echo "1+2+..+9+10=$sum"

[root@centos7 bin 15:18:18]# bash for1.sh 
1+2+..+9+10=55

2.2.3 示例2:批量重命名文件

具体需求:将某个目录下文件名中字符串snap替换为pic

模拟:

bash 复制代码
[root@centos7 bin 15:18:26]# mkdir Pictures
[root@centos7 bin 15:37:04]# touch Pictures/snap-{1..10}.jpg
bash 复制代码
[root@centos7 bin 15:50:21]# cat for_2_rename.sh 
#!/bin/bash
for file in Pictures/snap*
do 
  file_old_name=$file
  file_new_name=${file_old_name/snap/pic}
  mv ${file_old_name} ${file_new_name}
done

执行效果如下:

bash 复制代码
[root@centos7 bin 15:49:57]# bash for_2_rename.sh 
[root@centos7 bin 15:50:04]# 
[root@centos7 bin 15:50:04]# ls Pictures/
pic-10.jpg  pic-2.jpg  pic-4.jpg  pic-6.jpg  pic-8.jpg
pic-1.jpg   pic-3.jpg  pic-5.jpg  pic-7.jpg  pic-9.jpg

2.2.4 示例3:批量创建用户

公司新入职一批员工,需要为这些员工创建账号。

  1. 员工姓名清单保存在staff.txt中,每行一个。

  2. 为每个员工创建一个初始密码,初始密码是8位随机值,要求登录后必须修改密码。

  3. 创建的结果要保存到users_info.conf中,格式为username: password。

准备员工姓名清单:

bash 复制代码
[root@centos7 bin 15:52:47]# vim staff.txt
[root@centos7 bin 16:15:34]# cat staff.txt 
jack
tom
zhangsan
laowang

脚本内容如下:

bash 复制代码
[root@centos7 bin 16:28:08]# cat for_3_users.sh 
#!/bin/bash

staff_name_file=staff.txt
staff_info_file=users_info.conf

if [ -a ${staff_name_file} -a -r ${staff_name_file} ];then
  for staff in $(cat ${staff_name_file})
  do
    useradd $staff
    password=$(date +%N | md5sum | head -c10)
    echo $password | passwd --stdin $staff &>/dev/null
    echo "$staff: $password" >> ${staff_info_file}
  done
else
  echo "${staff_name_file} is not exist."
fi

执行效果如下:

bash 复制代码
[root@centos7 bin 16:25:55]# bash for_3_users.sh 
[root@centos7 bin 16:28:03]# cat users_info.conf 
jack: 141a940129
tom: b1b23719df
zhangsan: 70745fb6dd
laowang: 594d0504bd

2.2.5 生成随机值常见方法:

  • 利用时间生成纳秒级别值:date +%N
bash 复制代码
[root@centos7 bin 16:04:25]# date +%N
456812617
  • mktemp命令创建一个临时目录,目录名是随机值。
bash 复制代码
[root@centos7 bin 16:05:14]# echo $(mktemp)
/tmp/tmp.ncZkKK9TYD
  • 利用环境变量RANDOM生成0~32767随机值。

2.3 总结:() [] ${}

  1. $() :命令替换
  2. $[]:数值计算
  3. ${}:变量替换

三、while/until

条件满足或者不满足,一直运行。

3.1 语法

3.1.1 while

条件满足,一直运行。

bash 复制代码
while 条件判断
do
  command
done

3.1.2 until

条件不满足,一直运行。满足条件,则终止运行。

3.2 实践

3.2.1 示例1:挣1个小目标

while_1_target.sh 脚本内容如下:

bash 复制代码
#!/bin/bash
target=100000000
money=100
while ((money<target))
do
   echo -n "I'm working hard ... "
   sleep 1
   money=$[ money+10000000 ]
   echo $money
done

# 执行结果
[root@centos7 bin 17:14:46]# bash while_1_target.sh 
I'm working hard ... 10000100
I'm working hard ... 20000100
I'm working hard ... 30000100
I'm working hard ... 40000100
I'm working hard ... 50000100
I'm working hard ... 60000100
I'm working hard ... 70000100
I'm working hard ... 80000100
I'm working hard ... 90000100
I'm working hard ... 100000100
[root@centos7 bin 17:15:01]# 

3.2.2 示例 2:监控 sshd 服务

开发脚本monitor_sshd.sh 实时监控sshd服务,实现以下功能:

  1. 如果sshd服务没有运行,则报告sshd服务状态到/tmp/sshd_status.log日志;同时启动sshd服务,启动的结果也写入/tmp/sshd_status.log日志。
  2. 如果sshd服务正常运行,则报告sshd服务状态,并写入/tmp/sshd_status.log日志
  3. 每隔3秒执行一次监控。

monitor_sshd.sh 脚本内容如下:

bash 复制代码
[root@centos7 bin 17:22:37]# cat monitor_sshd.sh 
#!/bin/bash

log_file=/tmp/sshd_status.log

while true
do
  status=$(systemctl is-active sshd)

  if [ "$status" == "active" ];then
    echo "$(date): sshd status is running." | tee -a ${log_file}
  else
    echo "$(date): sshd status is not running." | tee -a ${log_file}
    systemctl start sshd &>/dev/null && \
    echo "$(date): Start sshd success." | tee -a ${log_file} || \
    echo "$(date): Start sshd fail." | tee -a ${log_file}
  fi
  sleep 3

done

执行效果如下:

bash 复制代码
[root@centos7 bin 17:22:21]# bash monitor_sshd.sh 
Mon Apr 13 17:22:26 CST 2026: sshd status is running.
Mon Apr 13 17:22:29 CST 2026: sshd status is running.
Mon Apr 13 17:22:32 CST 2026: sshd status is running.
Mon Apr 13 17:22:35 CST 2026: sshd status is running.
^C

新开终端关闭sshd服务,监控日志变化

bash 复制代码
[root@centos7 bin 17:22:58]# systemctl stop sshd
bash 复制代码
[root@centos7 bin 17:23:17]# bash monitor_sshd.sh 
Mon Apr 13 17:25:09 CST 2026: sshd status is not running.
Mon Apr 13 17:25:09 CST 2026: Start sshd success.
Mon Apr 13 17:25:12 CST 2026: sshd status is running.
Mon Apr 13 17:25:15 CST 2026: sshd status is running.
相关推荐
Amelio_Ming2 小时前
linux内存管理-页面回收之LRU链表
linux·服务器
小米里的大麦3 小时前
01 在 CentOS 7 中安装 MySQL
linux·mysql·centos
我不是程序猿儿3 小时前
【嵌入式】面向 STM32 的 ADC 与 DMA 学习路线
linux·stm32·单片机·嵌入式硬件·学习
徐子元竟然被占了!!3 小时前
数字证书学习
linux·网络·学习
langmeng1103 小时前
Linux安装Kafka3.8.0版本不使用zookeeper
linux·运维·服务器
亚空间仓鼠3 小时前
Shell脚本详解:从理论到实践(二)
linux·运维·服务器
code_whiter3 小时前
初阶linux1(常见指令以及权限理解)
linux
平凡的阳阳3 小时前
千里通Linux盒子搭建FRP全教程:低成本实现内网穿透+代理服务器
linux·frp·内网穿透·代理·socks5·远程ssh
D4c-lovetrain3 小时前
Linux个人心得25 (mysql⑤)
linux·运维·mysql