【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)

简介: 【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)

流程控制语句

exit,break,continue

exit                    退出脚本

break                 跳出循环

continue            忽略当前剩余代码,从头继续执行

一、exit

1. [root@LB00 Day04]# cat liucheng.sh
2. #!/bin/bash
3. while true
4. do
5.  echo 1
6.  exit
7.  echo 2
8. done
9. echo 3
10. [root@LB00 Day04]# sh liucheng.sh
11. 1

二、break

1. [root@LB00 Day04]# cat liucheng.sh
2. #!/bin/bash
3. while true
4. do
5.  echo 1
6.  break
7.  echo 2
8. done
9. echo 3
10. [root@LB00 Day04]# sh liucheng.sh
11. 1
12. 3

三、continue

1. [root@LB00 Day04]# cat liucheng.sh
2. #!/bin/bash
3. while true
4. do
5.  echo 1
6.  continue
7.  echo 2
8. done
9. echo 3
10. [root@LB00 Day04]# sh liucheng.sh
11. 1
12. 1
13. 1
14. ......
15. 
16. #continu使用示例
17. [root@LB00 Day04]# cat liucheng.sh
18. #!/bin/bash
19. while true
20. do
21.   read -p "请输入密码: " pass
22.   if ! [ $pass == 123456 ];then
23.     echo "密码输入错误"
24.     continue
25.   else
26.     echo "密码输入正确"
27.     break;
28.   fi
29. done
30. echo "登录成功"
31. [root@LB00 Day04]# sh liucheng.sh
32. 请输入密码: 1
33. 密码输入错误
34. 请输入密码: 123456
35. 密码输入正确
36. 登录成功

函数

1、完成特定功能的代码块

2、可以复用

3、函数类似变量,先定义再调用,区别是变量不调用也会执行,但是函数不调用不执行

一、函数定义

1. [root@LB00 Day04]# cat fun.sh
2. #!/bin/bash
3. fun1(){
4.  echo "第一种函数定义方法"  
5. }
6. function fun2 {                    #注意不加括号有空格
7.  echo "第二种函数定义方法"
8. }
9. function fun3(){
10. echo "第三种函数定义方法"
11. }
12. fun1
13. fun2
14. fun3
15. [root@LB00 Day04]# sh fun.sh
16. 第一种函数定义方法
17. 第二种函数定义方法
18. 第三种函数定义方法

与变量不同,函数不调用不执行,变量不调用也执行

1. [root@LB00 Day04]# cat fun.sh
2. #!/bin/bash
3. name=koten
4. fun1(){
5.  echo "第一种函数定义方法"  
6. }
7. function fun2 {
8.  echo "第二种函数定义方法"
9. }
10. function fun3(){
11. echo "第三种函数定义方法"
12. }
13. [root@LB00 Day04]# sh -x fun.sh
14. + name=koten

想在当前shell执行,直接source脚本或者. 脚本即可,跟变量同理

1. [root@LB00 Day04]# source fun.sh 
2. [root@LB00 Day04]# echo $name
3. koten
4. [root@LB00 Day04]# fun1
5. 第一种函数定义方法

二、函数传参

与脚本传参不同,函数中不能直接接受shell的传参

错误方式

1. [root@LB00 Day04]# cat chuancan.sh
2. #!/bin/bash
3. fun1(){
4.  if [ -f $1 ];then
5.    echo 文件存在
6.  else  
7.    echo 文件不存在
8.  fi
9. }
10. fun1
11. [root@LB00 Day04]# sh chuancan.sh /etc/passwd  #虽然显示存在 
12. 文件存在
13. [root@LB00 Day04]# sh -x chuancan.sh /etc/passwd  #但是看流程,函数中并没有显示
14. + fun1
15. + '[' -f ']'
16. + echo 文件存在
17. 文件存在

正确用法,直接写到调用名称后面

1. [root@LB00 Day04]# cat chuancan.sh
2. #!/bin/bash
3. fun1(){
4.  if [ -f $1 ];then
5.    echo 文件存在
6.  else  
7.    echo 文件不存在
8.  fi
9. }
10. fun1 $1
11. [root@LB00 Day04]# sh chuancan.sh /etc/passwd
12. 文件存在

注意区分脚本中的参数与函数中的参数

1. [root@LB00 Day04]# cat chuancan.sh
2. #!/bin/bash
3. fun1(){
4.  if [ -f $1 ];then        #这个是调用函数的传参
5.    echo $1 文件存在
6.  else  
7.    echo $1 文件不存在
8.  fi
9. }
10. fun1 $2 $1    #这个是执行脚本时候的传参
11. [root@LB00 Day04]# sh chuancan.sh /etc/hosts /etc/passwd
12. /etc/passwd 文件存在

也可以通过变量的方式传参,一开始定义好变量

1. [root@LB00 Day04]# cat chuancan.sh
2. #!/bin/bash
3. file=$1
4. fun1(){
5.  if [ -f $file ];then
6.    echo $file 文件存在
7.  else  
8.    echo $file 文件不存在
9.  fi
10. }
11. fun1
12. [root@LB00 Day04]# sh chuancan.sh /etc/passwd
13. /etc/passwd 文件存在

三、函数变量

函数中可以调用shell脚本的变量

在函数中定义的变量可以只在函数体中生效,在shell中不生效

1. #正常是在函数体内外都会生效
2. [root@LB00 Day04]# cat bianliang.sh
3. #!/bin/bash
4. fun1(){
5.  name=koten
6.  echo $name
7. }
8. fun1
9. echo $name
10. [root@LB00 Day04]# sh bianliang.sh
11. koten
12. koten
13. 
14. #只在函数体中生效
15. [root@LB00 Day04]# cat bianliang.sh
16. #!/bin/bash
17. fun1(){
18.   local name=koten
19.   echo $name
20. }
21. fun1
22. echo $name
23. [root@LB00 Day04]# sh bianliang.sh
24. koten
25. 
26. [root@LB00 Day04]#

四、函数返回值

exit和return都可以定义

1. [root@LB00 Day04]# cat fanhuizhi.sh 
2. #!/bin/bash
3. if [ -f $1 ];then
4.  echo "$1 存在"
5.  exit 100
6. else 
7.  echo "$1 不存在"
8.  exit 50
9. fi
10. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
11. /etc/passwd 存在
12. [root@LB00 Day04]# echo $?
13. 100
14. 
15. [root@LB00 Day04]# cat fanhuizhi.sh
16. #!/bin/bash
17. fun1(){
18.   if [ -f $1 ];then
19.     echo "存在"
20.     return 100
21.   else
22.     echo "不存在"
23.     return 99
24.   fi
25. }
26. fun1 $?
27. echo $?
28. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
29. 不存在
30. 99

使用返回值的时候容易出错,我们要时刻注意返回值是否有因为执行了新的命令而刷新

如下所示的错误写法!

1. [root@LB00 Day04]# cat fanhuizhi.sh
2. #!/bin/bash
3. fun1(){
4. if [ -f $1 ];then
5.  return 100
6. else 
7.  return 50
8. fi
9. }
10. fun1 $1
11. [ $? -eq 50 ] && echo 文件不存在
12. [ $? -eq 100 ] && echo 文件存在
13. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdd
14. 文件不存在
15. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
16. [root@LB00 Day04]#

由于在执行完函数后又执行了$?与50的判断,所以判断后$?刷新成了其他数值,所以永远不会echo出文件存在,这种情况一般有两种解决办法。

1. [root@LB00 Day04]# cat fanhuizhi.sh 
2. #!/bin/bash
3. fun1(){
4. if [ -f $1 ];then
5.  return 100
6. else 
7.  return 50
8. fi
9. }
10. fun1 $1
11. [ $? -eq 50 ] && echo 文件不存在
12. echo $?
13. [ $? -eq 100 ] && echo 文件存在
14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
15. 1

一种是将两个条件表达式写成一个,在使用函数的返回值之前不执行其他命令。

1. [root@LB00 Day04]# cat fanhuizhi.sh 
2. #!/bin/bash
3. fun1(){
4. if [ -f $1 ];then
5.  return 100
6. else 
7.  return 50
8. fi
9. }
10. fun1 $1
11. [ $? -eq 50 ] && echo 文件不存在 || echo 文件存在
12. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
13. 文件存在
14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdddd
15. 文件不存在

另一种也是系统中常做的操作,就是当我们的函数体执行完毕后给一个变量,后面用变量去判断,这样$?有变化也没有关系,反正变量不会有变化。

1. [root@LB00 Day04]# cat fanhuizhi.sh
2. #!/bin/bash
3. fun1(){
4.    [ -f $1 ];then
5.  return 100
6. else 
7.  return 50
8. fi
9. }
10. fun1 $1
11. re=$?
12. [ $re -eq 50 ] && echo 文件不存在 
13. [ $re -eq 100 ] && echo 文件存在
14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd
15. 文件存在
16. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdddd
17. 文件不存在

扩展:反向破解MD5

下面是随机数的md5值,4个取了前8位,2两个取了前7位,通过脚本反向破解出随机数

1. echo $((RANDOM))|md5sum|cut -c1-8
2. 0b364f36
3. 7f1e6feb
4. c5b795e2
5. 5f8b9f68
6. echo $((RANDOM))|md5sum|cut -c1-7
7. 081691c
8. 76728eb

我们的思路就是利用for循环反向破解,优化就是尽可能少的操作,加快遍历速度,更快的破解出来

1. [root@LB00 Day04]# cat fanxiang.sh 
2. #!/bin/bash
3. for i in `seq 32767`
4. do
5.  md5=`echo $i|md5sum`
6.  md5_7=`echo $md5|cut -c1-7`
7.  md5_8=`echo $md5|cut -c1-8`
8.  if [ "$md5_7" == 081691c ];then
9.    echo $i $md5_7
10.   elif [ "$md5_7" == 76728eb ];then
11.     echo $i $md5_7
12. elif [ "$md5_8" == 0b364f36 ];then
13. echo $i $md5_8
14. elif [ "$md5_8" == 7f1e6feb ];then
15. echo $i $md5_8
16. elif [ "$md5_8" == c5b795e2 ];then
17. echo $i $md5_8
18. elif [ "$md5_8" == 5f8b9f68 ];then
19. echo $i $md5_8
20.   fi
21. done
22. [root@LB00 Day04]# sh fanxiang.sh
23. 691 c5b795e2
24. 5343 081691c
25. 11902 7f1e6feb
26. 21364 76728eb
27. 25375 5f8b9f68
28. 30458 0b364f36

我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
6月前
|
运维 Java Shell
Linux非常详细的shell运维脚本一键启动停止状态SpringBoot打成可运行jar包
Linux非常详细的shell运维脚本一键启动停止状态SpringBoot打成可运行jar包
287 0
|
6月前
|
Shell
shell中并发执行多个进程
shell中并发执行多个进程
634 4
|
Shell
我们一起来学Shell - shell的并发及并发控制
我们一起来学Shell - shell的并发及并发控制
310 0
|
1月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
49 2
|
2月前
|
Ubuntu Shell Linux
Shell 流程控制语句
Shell 流程控制语句
22 6
|
3月前
|
运维 监控 Shell
自动化运维之宝:编写高效的Shell脚本
【8月更文挑战第31天】在运维的世界里,Shell脚本是一把瑞士军刀,它让日常任务变得简单而高效。本文将通过浅显易懂的语言和实际案例,带你领略Shell脚本的魅力,并教你如何打造属于自己的自动化工具箱。无论你是初学者还是资深运维,这篇文章都将为你打开一扇窗,让你看到不一样的风景。让我们一起探索Shell脚本的世界吧!
|
5月前
|
SQL 存储 关系型数据库
精通MySQL:从基础到高级运维实战
第一章:MySQL入门与基础 1.1 MySQL概述 简要介绍MySQL的历史、发展及其在数据库领域的地位
|
6月前
|
运维 Linux Shell
day02-Linux运维-系统介绍与环境搭建_硬件 系统核心 解释器shell 外围操作系统
day02-Linux运维-系统介绍与环境搭建_硬件 系统核心 解释器shell 外围操作系统
|
6月前
|
Shell
Shell脚本之流程控制语句
Shell脚本之流程控制语句
|
6月前
|
供应链 JavaScript Shell
供应链投毒预警 | 恶意NPM包利用Windows反向shell后门攻击开发者
本周(2024年02月19号),悬镜供应链安全情报中心在NPM官方仓库(https://npmjs.com)中发现多起NPM组件包投毒事件。攻击者利用包名错误拼写方式 (typo-squatting)在NPM仓库中连续发布9个不同版本的恶意包,试图通过仿冒合法组件(ts-patch-mongoose)来攻击潜在的NodeJS开发者。
122 2