shell编程-循环

shell编程-循环

循环分类

# 当型循环
while 当什么情况发生的时候 
当什么模式,后面[ 条件 ]
只要条件满足成立时我就循环
循环到这个条件不满足

# 直到型循环
do_until # 很少 压根不用
后面接条件表达式
这个条件只要不满足就一直循环
循环到满足为止

# 通用型循环
for #最常用的
基本while能做的for也能做
死循环:for (( ; ; ))

for循环应用场景

[root@web02 test]# cat 1.txt
www.yys.com  xxx
blog.yys.com yyy
zh.yys.com   zzz

[root@web02 test]# cat 1.sh 
#!/bin/bash
for domain in `cat 1.txt`;do
    echo "----------------"
    echo $domain
done

[root@web02 test]# sh 1.sh
----------------
www.yys.com
----------------
xxx
----------------
blog.yys.com
----------------
yyy
----------------
zh.yys.com
----------------
zzz

#!/bin/bash
for n in `seq 10`;do
    echo "----------------"
    echo $n
done

while循环

# 第一种写法
while [ 条件表达式 ]; do
    cmd1
    cmd2
    cmd3
    ...
done

# 第二种
while [ 条件表达式 ]
do
    cmd1
    cmd2
    cmd3
    ...
done

## while死循环 while true使用场景多,多数使用
while true;do     #条件为真
    echo 'heihei'
    sleep 1
done

#!/bin/bash
while [ 1 -eq 1 ];do  #条件为真
    echo 'hoho'
    sleep 2
done

#!/bin/bash
while :;do  #纯粹的死循环
    echo 'haha'
    sleep 2
done

while模拟for循环seq10

## while打出1-10
#!/bin/bash
i=1   ## 定义变量i=1
while [ $i -lt 11 ];do  ## 变量i小于11时 
    echo $i  ## 打印变量i
    ((i++))  ## i自增
done

使用while循环实现1加到100的值

#!/bin/bash
i=1
n=0
while [ $i -le 100 ];do
        n=$((i + n))
        ((i++))
done

echo '1-100的总和为:'$n

#!/bin/bash
i=1
n=0
while [ $i -le 100 ];do
       ((n=i+n))
        ((i++))
done

echo '1-100的总和为:'$n

img

直到型循环(忘记他)

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until循环更加有用。

# 第一种写法
until [ 条件表达式 ]; do
    cmd1
    cmd2
    cmd3
    ...
done

# 第二种
until [ 条件表达式 ]
do
    cmd1
    cmd2
    cmd3
    ...
done

#!/bin/bash
n=0
until [ $n -gt 10 ];do
       echo $n
        ((n++))
done

for循环语法

  • 语法一:无法指定循环次数,表达式有多少内容就循环多少次
for var in 变量表达式;do
  cmd1
  cmd2
done

for var in 变量表达式
do
  cmd1
  cmd2
done

# 变量表达式:
1.可以是以空格为分隔符的字符串
2.可以是以空格为分隔符的数字
3.可以是数组
4.可以是命令结果 seq 10
5.可以是文件内容(但是要注意for并不是按行读取,如果每一行都没有空格还行,但是一旦遇到空格就...)

# 例:
## 循环以空格为分隔符的字符串
## 横向排列
#!/bin/bash
for name in "ljy yl hhh";do
        echo $name
done

[root@web02 test]# sh 1.sh 
ljy yl hhh

## 竖向排列
[root@web02 test]# cat 1.sh
#!/bin/bash
for name in "ljy" "yl" "hhh";do
    echo $name
done
[root@web02 test]# sh 1.sh 
ljy
yl
hhh

## 循环以空格为分隔符的数字
[root@web02 test]# cat 1.sh 
#!/bin/bash
for num in 1 2 3 4 5
do
    echo $num
done
[root@web02 test]# sh 1.sh 
1
2
3
4
5

for num in {1..10};do
  echo $num
done
[root@web02 test]# sh 1.sh 
1
2
3
4
5
6
7
8
9
10

for zm in {a..c};do
  echo $zm
done
[root@web02 test]# sh 1.sh 
a
b
c

## 循环数组
name=("www" "ccc" "bbb" "ddd")
for str in ${name[*]};do
  echo $str
done

##  循环命令结果
for file in `ls -1 /`;do
  echo $file
done
[root@web02 test]# sh 1.sh 
www
ccc
bbb
ddd

for text in `cat /etc/passwd`;do
  echo $text
done
[root@web02 test]# sh 1.sh 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP
User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd
Network
Management:/:/sbin/nologin
dbus:x:81:81:System
message
bus:/:/sbin/nologin
polkitd:x:999:998:User
for
polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated
SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:Nginx
web
server:/var/lib/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB
Server:/var/lib/mysql:/sbin/nologin
rpc:x:32:32:Rpcbind
Daemon:/var/lib/rpcbind:/sbin/nologin
redis:x:997:995:Redis
Database
Server:/var/lib/redis:/sbin/nologin
tomcat:x:53:53:Apache
Tomcat:/usr/share/tomcat:/sbin/nologin
rpcuser:x:29:29:RPC
Service
User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous
NFS
User:/var/lib/nfs:/sbin/nologin
  • 语法二:可指定循环次数格式
for((i=1;i<=10;i++));do
  echo $i
done

for也可以死循环

for (( ; ; ));do
  echo 123
  sleep
done

循环控制语句

continue

break

break跳出循环

break命令允许跳出所有循环(终止执行后面的所有循环)。

下面的例子中,脚本进入死循环直至用户输入数字大于5。

要跳出这个循环,返回到shell提示符下,需要使用break命令。

[root@zabbix01 ~]# vim break.sh
#!/bin/bash
while true;do
  read -p 'Please Input A Number: ' num
  if [ $num -ne 5 ];then
      echo "你输入的是 $num"
  else
      break
  fi
done

[root@zabbix01 ~]# sh break.sh
Please Input A Number: 1
你输入的是 1
Please Input A Number: 2
你输入的是 2
Please Input A Number: 3
你输入的是 3
Please Input A Number: 4
你输入的是 4
Please Input A Number: 5

#!/bin/bash
n=0
while [ $n -lt 10 ];do
        ((n++))
        if [ $n -eq 5 ];then
                break
        fi
                echo $n
done
[root@web02 test]# sh break.sh 
1
2
3
4

continue 跳出循环

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环

#!/bin/bash
while true;do
  read -p 'Please Input A Number: ' num
  if [ $num -ne 5 ];then
      echo "你输入的是 $num"
  else
      continue
  fi
done
[root@web02 test]# sh continue.sh 
Please Input A Number: 1
你输入的是 1
Please Input A Number: 2
你输入的是 2
Please Input A Number: 3
你输入的是 3
Please Input A Number: 4
你输入的是 4
Please Input A Number: 5
Please Input A Number: 6
你输入的是 6

#!/bin/bash
n=0
while [ $n -lt 10 ];do
        ((n++))
        if [ $n -eq 5 ];then
                continue
        fi
                echo $n
done
[root@web02 test]# sh continue.sh 
1
2
3
4
6
7
8
9
10

while读取文件

## 方法一:使用exec读取文件内容,然后进入while循环
#!/bin/bash
exec < 1.txt
while read line;do
        echo '---------'
        echo $line
done

## 方法二:使用管道符,将文件内容交给while循环
cat 1.txt|while read line_name;do

  echo $line_name
  echo "------"
done

## 方法三:使用标准输入,将文件内容交给while循环
#!/bin/bash 
while read name;do
  echo $name
  echo "------"
done < 1.txt

while读文件练习

写一个脚本,读取下面文件内容,并算出所有人年龄总和

[root@zabbix01 ~]# cat student.txt
写一个脚本,读取下面文件内容,并算出所有人年龄总和
wyd 0
hhh 1
tls 18
zls 18
yl  2
lyf 0
hyb 8

#!/bin/bash
name_age=0
while read line;do
        age=`echo "$line"|awk '{print $2}'`
        ((name_age+=age))
done < student.txt
echo "所有人年龄总和为:"$name_age

跳板机作业

/etc/passwd

1.传输功能 传输文件

2.登陆框
角色
    - 运维 ops 能访问所有的机器
    - 开发 dev web01 web02 web03
    - 测试 test lb01 lb02
数据库 (user.txt)
用户名 密码 角色
ljy   123  ops

文件传输功能
    - 请输入要传输的文件 
    检查是否有输入

    - 要输入传输的目标服务器并支持多个服务器
     显示主机清单
     +---------+
     |  web01  |
     +---------+
     |  web02  |
     +---------+
     |  web03  |
     +---------+
     |  lb01   |
     +---------+
     |  lb02   |
     +---------+
     |  db01   |
     +---------+
     |  db02   |
     +---------+
     |  db03   |
     +---------+
检测服务器信息
    - 内存
    - 磁盘
    - CPU
    查看多台服务器的所有信息

3.远程连接 什么角色能连接什么机器
#!/bin/bash

# 用户数据库信息
user_file="user.txt"

# 登录验证
login() {
  read -p "请输入用户名: " username
  read -sp "请输入密码: " password
  echo

  # 从用户列表文件中查找对应的角色
  role=$(grep -E "^$username " "$user_file" | awk '{print $3}')
  if [[ -z "$role" ]]; then
    echo "用户名或密码错误!"
    exit 1
  fi

  echo "登录成功,欢迎您,$username!"
}

# 文件传输功能
file_transfer() {
  read -p "请输入要传输的文件路径: " file_path
  if [[ -z "$file_path" ]]; then
    echo "未输入文件路径!"
    return
  fi

  # 服务器清单
  server_list=("web01" "web02" "web03" "lb01" "lb02" "db01" "db02" "db03")
  cat >EOF
     +---------+
     |  web01  |
     +---------+
     |  web02  |
     +---------+
     |  web03  |
     +---------+
     |  lb01   |
     +---------+
     |  lb02   |
     +---------+
     |  db01   |
     +---------+
     |  db02   |
     +---------+
     |  db03   |
     +---------+
  EOF
  echo "请选择目标服务器(支持多选,用空格分隔):"
  for ((i=0; i<${#server_list[@]}; i++)); do
    echo "$((i+1)). ${server_list[i]}"
  done

  read -p "输入服务器序号(多个序号以空格分隔): " selected_servers
  if [[ -z "$selected_servers" ]]; then
    echo "未选择目标服务器!"
    return
  fi

  # 检查文件是否存在
  if [[ ! -f "$file_path" ]]; then
    echo "文件 $file_path 不存在!"
    return
  fi

  IFS=" " read -ra selected_servers_arr <<< "$selected_servers"

  for server_index in "${selected_servers_arr[@]}"; do
    if [[ "$server_index" -gt 0 && "$server_index" -le ${#server_list[@]} ]]; then
      server=${server_list[$((server_index-1))]}
      echo "正在传输文件到服务器 $server ..."
      # 执行文件传输操作,例如使用 scp 命令
      # scp "$file_path" "$server"
      echo "传输文件到服务器 $server 完成"
    fi
  done
}

# 检测服务器信息
check_server_info() {
  # 服务器清单
  server_list=("web01" "web02" "web03" "lb01" "lb02" "db01" "db02" "db03")

  echo "请选择要检测信息的服务器(支持多选,用空格分隔):"
  for ((i=0; i<${#server_list[@]}; i++)); do
    echo "$((i+1)). ${server_list[i]}"
  done

  read -p "输入服务器序号(多个序号以空格分隔): " selected_servers
  if [[ -z "$selected_servers" ]]; then
    echo "未选择服务器!"
    return
  fi

  IFS=" " read -ra selected_servers_arr <<< "$selected_servers"

  for server_index in "${selected_servers_arr[@]}"; do
    if [[ "$server_index" -gt 0 && "$server_index" -le ${#server_list[@]} ]]; then
      server=${server_list[$((server_index-1))]}
      echo "正在检测服务器 $server 的信息..."
      # 执行服务器信息检测操作,例如使用 ssh 命令远程连接并执行相关命令
      # ssh "$server" "free -m; df -h; top -n 1"
      echo "服务器 $server 的信息检测完毕"
    fi
  done
}

# 主程序
login

case "$role" in
  "ops")
    echo "您是运维角色,可以访问所有的机器"
    file_transfer
    check_server_info
    ;;
  "dev")
    echo "您是开发角色,可以访问 web01、web02 和 web03 机器"
    file_transfer
    ;;
  "test")
    echo "您是测试角色,可以访问 lb01 和 lb02 机器"
    check_server_info
    ;;
  *)
    echo "未知角色!"
    exit 1
    ;;
esac
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇