shell循环

shell循环

为什么使用循环

1.减少代码量

2.有些时候,只能用循环,不规律的情况下

3.读取文件内容

4.死循环

循环的分类

  • 当型循环 while
  • 直到型循环 do until
  • 通用循环 for

while 循环语法

while 条件;do
  chmd1
done

while 条件
do
  cmd1
  cmd2
done

## 死循环
while true;do
  echo '123'
done

while [ 1 -eq 1 ];do
  echo 456
  sleep 3
done

## 开关的方式终结死循环
flag=true
num=1

while $flag;do
  echo $num
  if [ $num -eq 10 ];then
    flag=false
  fi
  ((num++))
done

使用while模拟seq命令

#!/bin/bash
#while true;do
# echo '123'
#done
#

#while [ 1 -eq 1 ];do
# echo 456
# sleep 3
#done

num=1
while [ $num -le $1 ];do
  echo $num
  ((num++))
done

使用while从1加到100

num=0
count=1

while [ $count -le 100 ];do
  ((num+=count))
  ((count++))
done
echo $num

until循环(忘记)

# 语法:
until <条件表达式>;do
  cmd1
done

# 例
#!/bin/bash
until false;do
  echo 123
  sleep 1
done

for循环

# 语法一:
for 变量名 in 变量表达式;do
  cmd1
  cmd2
done

## 变量表达式
1.可以是以空格为分隔符的字符串
file_name="/etc/passwd /etc/shadow /etc/gshadow /etc/group"

for file in $file_name;do
  echo $file
  echo '--- 分隔符 ---'
done

2.可以是以空格为分隔符的数字
for n in 1 2 3 4 5;do
  echo $n
done

3.可以是一个命令的结果
for number in `ls /`;do
  echo $number
done

for number in `seq 10`;do
  echo $number
done

4.可以是数组
array=(zls cls wls)
for name in ${array[@]};do
  echo $name
done

5.文件内容
但是要注意for并不是按行读取,如果每一行都没有空格还行,但是一旦遇到空格就...
for name in `cat student.txt`;do
  echo $name
done

# 语法二:
类C语言的语法
for((i=1;i<="$1";i++));do
  echo $i
done

## for的死循环
for (( ; ;));do
  echo 123
  sleep 1
done

循环控制语句

break跳出循环

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

num=0
for(( ; ;));do
  ((num++))
  echo $num
  sleep 1
  if [ $num -eq 10 ];then
    break 1
  fi
done

echo "这里是循环之外..."

continue跳出循环

它不会跳出所有循环,仅仅跳出当前循环。

for n in `seq 10`;do
  if [ $n -eq 5 ];then
    continue 1
  fi
  echo $n
done

echo "这里是循环之外..."

注意:多层循环嵌套的时候,break或者continue写在哪个循环中,就只跳出一层循环(break和continue后面的数字 是指定循环层数)

#!/bin/bash

for name in `cat name.txt`;do
  for age in `cat age.txt`;do
    echo "$name $age"
    if [ $age -eq 11 ];then
      break 1
    fi
  done
done

for name in `cat name.txt`;do
  for age in `cat age.txt`;do
    echo "$name $age"
    if [ $age -eq 11 ];then
      break 2
    fi
  done
done

while读取文件内容

# 1.方法一:
cat 文件名|while read 变量名;do
  cmd1
  cmd2
done

例:
cat name.txt|while read line_name;do
  echo $line_name
done

# 2.方法二:
while read 变量名;do
  cmd1
  cmd2
done < 文件名

while read line_name;do
  echo $line_name
done < name.txt

# 3.方法三
exec < name.txt

while read line_name;do
  echo $line_name
done

while读取文件练习

文件内容
曾老湿 18
苍井空 20
武藤兰 33
天海翼 32
西野翔 18

#!/bin/bash
count=0
while read line;do
  age=${line##* }
  echo $((count+=age))
done < student.txt
echo $count

日志分析案例

写一个shell脚本,防止 DDOS 攻击,先分析日志,监控某一个IP并发连接数,若短时内PV达到100阈值,则调用防火 墙命令,封掉该IP。

可以分析nginx日志或者查看当前网络连接数 ss -ant 或者 netstat -ant

# 每个IP的并发数
awk '/^tcp/{print $4}' netstat.log|sort -nr|uniq -c

# 每个IP的访问次数
ip_access=`awk '/^tcp/{print $4}' netstat.log|sort -nr|uniq -c|awk '{print $1}'`

if [ $ip_access -gt 100 ];then
  firewall-cmd --add-source=$ip --zone=drop
fi

# vim ip.sh
#!/bin/bash

ip_access=`awk '/^tcp/{print $4}' netstat.log|sort -nr|uniq -c|awk -F '[ :]+' '{print $2","$3}'`

for line in $ip_access;do
  count=${line%%,*}
  ip=${line##*,}
  if [ $count -gt 100 ];then
    firewall-cmd --add-source=$ip --zone=drop
  fi
done

随机文件名

# 取随机数方法
1.md5
date +%N|md5sum|cut -c 1-10
2.mkpasswd
mkpasswd -l 10
3.random
echo $RANDOM|md5sum|cut -c 1-10
4.tr
tr -cd 'a-z' </dev/urandom|head -c 10

在指定目录下,通过随机10个小写字母,然后生成10文件名为:随机字母_zls.txt的文件

随机数:tr -cd 'a-z' </dev/urandom|head -c 10
for((i=1;i<=10;i++));do
  ran=`tr -cd 'a-z' </dev/urandom|head -c 10`
  touch /tmp/${ran}_zls.txt
done

批量修改文件名

将/tmp/下面所有的txt文件修改为TXT

# 1.变量子串
file_path=`ls /tmp/*.txt`

for file_name in $file_path;do
  mv $file_name ${file_name/txt/TXT}
done

# 2.替换
file_path=`ls /tmp/*.TXT`

for file_name in $file_path;do
  new_name=`echo $file_name|tr 'TXT' 'txt'`
  mv $file_name $new_name
done

# 3.rename
file_path=`ls /tmp/*.txt`

for file_name in $file_path;do
  rename ${file_name%%.*}.txt ${file_name%%.*}.TXT /tmp/*.txt
done

## 创建5个用户,并且给随机密码
seq 5|awk '{print "pass=`echo $RANDOM|md5sum|cut -c 1-10`;useradd wls"$1";echo cls"$1":$pass >> /tmp/pass2.txt;echo $pass|passwd --stdin cls"$1}'|bash

快速扫描指定网段中存活的机器

. /etc/init.d/functions

for n in `seq 255`;do
{
  ping -c 1 -W 0.2 -i 0.5 192.168.3.$n &>/dev/null
  if [ $? -eq 0 ];then
    action "192.168.3.$n" /bin/true
  fi
} &
usleep 200
done

nmap -n -sn 10.0.0.0/24

figlet命令

[root@zabbix01 ~]# figlet zls
[root@zabbix01 ~]# showfigfonts
[root@zabbix01 ~]# figlet zls -f banner
[root@zabbix01 ~]# watch -n1 "date +%D%n%T|figlet -k"

作业

优化登录框

num=0
flag=true
while $flag;do
  echo -e "\n-------- 登录界面 --------"
  read -p "用户名: " user_name
  read -p "密码: " user_pass
  user_count=`awk '{print $1}' $db_file | grep -cw "$user_name"`
  if [ $user_count -eq 0 ];then
    while $flag;do
      echo -e "\n-------- 注册界面 --------"
      read -p "注册用户名: " user_name
      user_count=`awk '{print $1}' $db_file | grep -cw "$user_name"`
      if [ $user_count -eq 0 ];then
        read -p "注册密码: " user_pass1
        read -p "确认密码: " user_pass2
          if [ $user_pass1 == $user_pass2 ];then
            echo "$user_name 注册成功"
            echo "$user_name $user_pass1" >> $db_file
            break
        else
          echo "两次密码不一致"
          ((num++))
          if [ $num -eq 3 ];then
            flag=false
          fi
        fi
      fi
    done
  else
    pass=`grep -w "$user_name $user_pass" $db_file |awk '{print $2}'`
    if [ "$user_pass" == "$pass" ];then
      echo "登录成功"
      exit 0
    else
      echo "密码错误请重新输入"
      ((num++))
      if [ $num -eq 3 ];then
        echo "密码输入错误三次,程序退出"
        flag=false
      fi
    fi
  fi
done
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值