shell编程-流程控制

3 篇文章 0 订阅

shell编程-条件结构

测试-----test 条件

#条件为真返回 0,条件为假返回 1 #语法------[ 条件 ]
test 能够理解3中类型的表达式 
1.文件测试
2.字符串比较
3.数字比较
​
字符串
 -n STRING   -n  字符串的长度不是零,成功。   
 -z STRING   -z   字符串长度是零,成功 #对于未定义或赋予空值的变量将是为空串。   
 STRING1 = STRING2  (等于)
 STRING1 != STRING2  (不等于)
​
# vim string.sh
#!/usr/bin/bash
read -p "请输入你的密码: " a
pass=123456
if [ -z $a ];then
        echo "您输入的密码不能为空"
        exit 1
else
        if [ $a = $pass ];then
                echo "登录成功"
                break
        else
                echo "您的密码输入有误,请重新输入"
        fi
fi
​
#数字
    -eq(equal) 等于
    -ne(not equal) 不等于
    -ge(Greater than or equal to) 大于等于 
    -le(Less than or equal to) 小于等于 
    -gt(greater than) 大于
    -lt(less than) 小于 
​
#文件————判断测试
    -f 存在且是普通文件
    -d 存在且是目录
    -h 存在且是符号链接 
    -b 块设备
    -c 字符设备
    -e 文件或者目录存在

shell分支if语句

流控制:
•在一个shell脚本中的命令执行顺序称作脚本的流。大多数脚本会根据一个或多个条件来改变它们的流。 
•流控制命令:能让脚本的流根据条件而改变的命令称为条件流控制命令 
•exit语句:退出程序的执行,并返回一个返回码,返回码为0正常退出,非0为非正常退出,例如: 
•exit 0
​
条件判断语法:
if [ 判断条件 ]---代码返回0表示真,非0为假.在[ 和 ] 以及操作符和操作数之间添加空格是必需的
if语句语法如下: 
if [ list1 ];then   list1:你的测试条件,你要测试什么,对什么内容做判断
    list2
elif [ list3 ];then     ---------------> 接着在怎么做。(多条件判断)
    list4
else           ---------------> 如果前面的命令没有执行成功那就执行else下面的命令。
    list5
fi

多个条件联合
&&:逻辑与,前面执行成功,后面才执行。前面命令执行失败,后面命令也不执行
if [ $condition1 ] && [ $condition2 ];then 
if [[ $condition1 && $condition2 ]];then
||:逻辑或,前面执行失败,后面执行,前面命令执行成功,后面不执行。
if [ $condition1 ] || [ $condition2 ];then 
if [[ $condition1 || $condition2 ]];then
​
例:
[root@linux-server ~]# cd /opt/test/script/
[root@linux-server script]# vim testif.sh
#!/bin/bash
read -p "请输入号码: " num 
if [ $num = 1 ];then
        echo "1"
elif [ $num = 2 ];then
                echo "2"
else 
                echo "输入有误!"
fi
[root@linux-server script]# chmod +x testif.sh
​
例:脚本if.sh,必须在脚本后加上适当的参数脚本才能正确执行
[root@linux-server script]# vim if.sh
#!/bin/bash
if [ "$1" = "hello" ]; then
        echo "Hello! How are you ?"
elif [ "$1" = "" ]; then
                echo "You MUST input parameters"
else
                echo "The only accept parclear ameter is hello"
fi
[root@linux-server script]# chmod +x if.sh
测试:
[root@linux-server script]# ./if.sh 
[root@linux-server script]# ./if.sh hello
[root@linux-server script]# ./if.sh 434
​
练习
1.测试ip地址主机位从2到100的机器是否存活,并把存活的机器记录到文本文件alivehost.txt内。(使用ping命令)
案例
#!/usr/bin/bash
ip=192.168.198
for i in {2..100}
do
        ping -c1 $ip.$i &> /dev/null
                if [ $? -eq 0 ];then
                        echo "$ip.$i is up" >> activehost.txt
                else
                        echo "$ip.$i is down"
                fi
done
​
作业
1. 判断一个用户是否存在
2. 判断当前内核主版本是否为3,且次版本是否大于10
#!/bin/bash
kernel_version=$(uname -r)
m_ver=`uname -r | awk -F'.' '{print $1}'`
s_ver=$(uname -r | awk -F'.' '{print $2}')
if [[ $m_ver == 3 && s_ver -ge 10 ]]; then
        echo "主版本为3且此版本大于等于10"

else
        echo "不符合"
fi

2. 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,
不能用自动修复配置yum源,安装完vsftpd后测试是否能用).
#!/bin/bash
#检查vsftpd软件包是否已安装
if ! rpm -q vsftpd >/dev/null; then
        echo "vsftpd软件包未安装"
        #检查yum是否可用
        if ! which yum >/dev/null; then
                echo "yum命令不可用,正在修复yum源……"
                #修复yum源
                yum -y install expel-release
                curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
                yum clean all
                yum makecache
                #再次检查yum命令是否可用
                if ! rpm -q yum >/dev/null; then
                        echo "修复失败,请手动修复yum源后重新运行脚本"
                        exit 1
                fi
        fi
        #使用yum安装vsftpd软件包
        yum -y install vsftpd
        #检查安装结果
        if [ $? -eq 0 ]; then
                echo "vsftpd安装成功"
                echo "正在监测vsftpd是否可用..."
        #测试vsftpd
                systemctl start vsftpd
                systemctl status vsftpd
                if [ $? -eq 0 ]; then
                        echo "vsftpd服务正常运行"       
                        exit 0
                else
                        echo "vsftpd服务未能正常启动,请检查配置"
                        exit 1
                fi
        else
                echo "vsftpd软件包安装失败"
                exit 1
        fi
else
        echo "vsftpd软件包已安装 "
fi

4. 判断指定的主机是否能ping通,必须使用$1变量
#!/bin/bash
read -p "输入要Ping的地址:" host    # 定义要ping的主机

ping_result=$(ping -c 4 $host)     # 尝试ping主机,-c 4 表示发送4个ICMP请求包

if [ $? -eq 0 ]; then              # 检查ping命令的退出状态
    echo "主机 $host 可达。"

    # 使用grep和awk来解析ping输出中的统计信息
    packets_sent=$(echo "$ping_result" | grep "transmitted" | awk '{print $1}')
    packets_received=$(echo "$ping_result" | grep "received" | awk '{print $1}')
    packet_loss=$(echo "$ping_result" | grep "packet loss" | awk '{print $1}')
    rtt_min=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $3}')
    rtt_avg=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $4}')
    rtt_max=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $5}')

    echo "发送的数据包: $packets_sent"
    echo "接收的数据包: $packets_received"
    echo "数据包丢失率: $packet_loss%"
    echo "RTT 最小值: $rtt_min ms"
    echo "RTT 平均值: $rtt_avg ms"
    echo "RTT 最大值: $rtt_max ms"
else
    echo "主机 $host 不可达。"
fi

shell 分支case语句

case 语句是 shell 流控制的第二种方式,语法如下: 
case $变量 in
     pattern1)
          list1
          ;;          ---------------结尾。
     pattern2)
          list2
          ;;
     ... ...
     patternN)
          listN
         ;;
    *)                -------------> 如果前面命令没有执行成功那么执行下面这个
         list*
         ;;
esac
​
命令;;表明流应该跳转到case语句的最后,类似C语言中的break指令。
第一行: 声明case关键字调用case语法, 紧跟的“变量”一般为用户的输入值, in代表从下方的各个模式进行匹配 
第2-4行: 匹配到“pattern1”后进行命令的输出或执行, pattern1: 一般为字符或数值
第11-12行: 当用户输入的字符不存在匹配模式时, 直接执行或打印*)下的命令或语句
​
​实例1
判断用户输入的是否是数字
#!/bin/bash
read -p "请输入:" input
case $input in
        ''|*[!0-9]*) #如果输入为空或包含非数字字符
                echo "输入的不是纯数字"
                ;;
        *)      #如果输入只包含数字
                echo -e  "输入的是纯数字\n"
                ;;
esac
实例2:
建立脚本case.sh,当执行时,要求我们在键盘输入适当的值(one|two|three),当输入正确时并打印,当输入错误 时会提示你,应该输入正确的值。
#!/usr/bin/env bash
while true; do
        read -p "请输入one、two或three:" input
        case $input in
                one)
                        echo "输入了one"
                        break
                        ;;
                two)
                        echo "输入了two"
                        break
                        ;;
                three)
                        echo "输入了three"
                        break
                        ;;
                *)
                        echo "输入错误,请重新输入"
                        ;;
        esac
done

示例2:

[root@linux-server script]# vim system_tools.sh
#!/usr/bin/env bash
cat <<-EOF 
+-------------------------------------------------------------------------+ 
|                             System_tools V1.0                           | 
+-------------------------------------------------------------------------+
|                     a. Stop And Disabled Firewalld.                     |
|                     b. Disabled SELinux Secure System.                  |
|                     c. Install Apache Service.                          |
|                     d. Quit                                             | 
+-------------------------------------------------------------------------+ 
EOF
echo "Please input your select: " && read var
case "$var" in
  	"a")
        systemctl stop firewalld && systemctl disable firewalld
				;; 
		"b")
				setenforce 0
				;; 
		"c")
				yum -y install httpd httpd-tools
				;; 
		"d")
				exit
				;; 
			*)
				echo "请按照上方提供的选项输入!!!"
				;; 
esac
[root@linux-server script]# chmod +x system_tools.sh
[root@linux-server script]# ./system_tools.sh

练习:
1.建立脚本service.sh,当执行的时候要求输入(1、2、3、4、5)时安装对应的httpd、vim、wget、更换aliyum等功能,当输入错误 时会提示你,应该输入正确的值。

shell编程-循环结构

for语句
for i in {取值范围}  #for是关键字 i是变量名 in是关键字
do                  #循环体的开始
                循环体
done                #循环体的结束
实战1:
[root@linux-server script]# vim for.sh
#!/usr/bin/env bash
#
# Author:
# Date: 2019/**/**
for i in {1..100} 
do
    echo $i 
done
[root@linux-server script]# vim for1.sh
#!/bin/bash
for (( i=1;i <= 5;i++ ))
do
                echo "$i"
done
[root@linux-server script]# chmod +x for1.sh 
[root@linux-server script]# ./for1.sh
参数解释:
默认值 i=1 
条件  i<=多少?取决于定义,为用户输入的变量,先条件成立在执行命令
增幅  i++  执行一次加一
​
区别:
i++===先赋值在运算
++i===先运算在赋值
例子
[root@localhost script]# i=1
[root@localhost script]# h=1
[root@localhost script]# let x=i++
[root@localhost script]# echo $x
1
[root@localhost script]# echo $i
2
[root@localhost script]# let y=++h
[root@localhost script]# echo $y
2
[root@localhost script]# echo $h
2

测试生产环境的主机存活性,将up的ip保存在一个文件中,将down的ip保存在一个文件中

[root@linux-server script]# vim ip.sh
#!/usr/bin/env bash
# Author: 
src_ip="192.168.246"
for i in {2..254}
do
        {
        ping -c1 $src_ip.$i &>/dev/null
        if [ $? -eq 0 ];then
                echo "alive: $src_ip.$i" >> ip_up.txt
                echo "alive: $src_ip.$i"
        else
                echo "down: $src_ip.$i" >> ip_down.txt
                echo "down: $src_ip.$i"
        fi
        } &
done
wait
echo "finish..."
[root@linux-server script]# chmod +x ip.sh 
[root@linux-server script]# ./ip.sh
参数详解:
wait:等待上面命令后台执行结束后(即上一个的进程终止),在执行下面的echo命令
{}加上就可以看成一个整体的进程

for循环批量创建用户

[root@linux-server script]# vim user.sh
#!/usr/bin/bash
read -p "请设置用户名/数量/密码: " prefix num pass
cat <<-EOF
用户前缀:$prefix
用户数量:$num
用户密码:$pass
EOF
for i in $(seq 1 $num)
do
user=$prefix$i
id $user &> /dev/null
if [ $? -eq 0 ];then
        echo "$user is already exist!"
        exit 0
else
        useradd $user &> /dev/null
        echo $pass | passwd --stdin $user &>/dev/null
fi
done
echo "starting create users..."
[root@linux-server script]# chmod +x user.sh 
[root@linux-server script]# ./user.sh
​
参数详解:
seq 打印序列号,命令用于产生从某个数到另外一个数之间的所有整数。
​
为什么不能在{ }中使用变量。
Bash中会最先展开{ }中的内容,这个时候$NUM还不会被具体的值替代,所以是i在循环中读取的是‘{1..$NUM}’的一个完整的字符串,输出时$NUM会被10替代,就有了'{1..10}'这样的结果。
seq序列
seq [OPTION]... FIRST INCREMENT LAST
seq 1 -1 10  生成从10到1的递减序列
seq 1  2 10  生成从1到10,步长为2的序列
seq a z      生成从a到z的字母序列:
while语句
while 条件  
do
        循环体
done
注意:while循环处理文件里面的行比较擅长,不管有没有空格都是一行。
​while关键字,条件和if的条件一样,#while循环当条件为真的时候进入循环,同时会一直循环,也就所说的死循环,为假时不循环

完善系统工具的输出及操作性

#通过一个文件批量创建用户:
#背景:写一个脚本,满足以下需求及应用,如一个文件的内容如下,根据文件内容实现批量创建用户,第一列为用户名,第二列为密码
[root@localhost script]# vim user_pass.txt #创建用户和密码文件
user1 qfedu123
user2 qfedu456
user3 qfedu567
user4 qfedu789
user5 qfedu012
[root@localhost script]# vim create_user.sh #编写脚本
#!/usr/bin/bash
​
[ $UID -ne 0 ] && exit 1
while read line
do
        user=`echo $line | awk '{print $1}'`
        pass=`echo $line | awk '{print $2}'`
        id $user &> /dev/null || useradd $user && echo $pass | passwd $user --stdin
done < /opt/test/script/user_pass.txt
[root@localhost script]# chmod +x create_user.sh 
[root@localhost script]# bash create_user.sh
​
案例二:
[root@linux-server script]# vim while.sh
#!/usr/bin/bash
while 1>0
do
cat <<-EOF 
+-------------------------------------------------------------------------+ 
|                            System_tools V1.0                            | 
+-------------------------------------------------------------------------+
|                      a. Stop And Disabled Firewalld.                    |
|                      b. Disabled SELinux Secure System.                 |
|                      c. Install Apache Service.                         |
|                      d. Quit                                            | 
+-------------------------------------------------------------------------+
EOF
echo " Please input your select: " && read var
case "$var" in
                                "a")
                                systemctl stop firewalld && systemctl disable firewalld
                                                        ;; 
                                "b")
                                sed -ri s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
                                                        ;; 
                                "c")
                                yum -y install httpd httpd-tools
                                                        ;; 
                                "d")
                                exit
                                ;; 
                                  *)
                                echo "请按照上方提供的选项输入!!!"
                                sleep 2
                                clear
                                ;; 
esac
done
[root@linux-server script]# chmod +x while.sh 
[root@linux-server script]# ./while.sh
​
案例三嵌套循环
[root@localhost script]# vim test4.sh
#!/usr/bin/bash
for i in {1..100}
do
while [ $i -lt 50 ]
do
        echo $i
        #let i++
done
done
[root@localhost script]# chmod +x test4.sh
[root@localhost script]# bash test4.sh
练习题:
1.输入用户输入的参数,直到用户输入 "end" 结束循环
2.给脚本service.sh进行修改,当执行的时候要求输入(1、2、3、4、5)时安装对应的httpd、vim、wget、更换aliyum等功能,当输入错误 时提示应该输入正确的值但是不会退出。
3.建立批量删除用户脚本
# vim deluser.sh
#!/usr/bin/bash
read -p "请输入用户名: " na
read -p "请输入要删除的个数? " num
echo $num
read -p "确认要删除$na[Y|y]: " x
if [ $x = Y ] || [ $x = y ];then
for i in $(seq 1 $num )
do
echo "$i"
user=$na"$i"
id $user
if [ $? -eq 0 ];then
        userdel -r $user
else
        exit 9
fi
done
fi
​
#chmod +x deluser.sh
#./deluser.sh
until语句
until 条件   #当后面的条件表达式为假的时候的才循环,为真的时候就停止了
do
循环体
done
[root@linux-server script]# cat until.sh 
#!/bin/bash
x=1
until [ $x -ge 10 ]
do
        echo $x
        x=`expr $x + 1` 
done
​
x=1
while [ ! $x -ge 10 ]
do
        echo $x
        x=`expr $x + 1`
done
[root@linux-server script]# chmod +x until.sh 
[root@linux-server script]# ./until.sh
循环控制
shift
shift命令
将命令行参数列表中的位置参数向左移动,并更新变量$1、$2等的值。
比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。
不带参数的shift命令相当于shift 1。
语法:shift [n]



#测试 shift 命令
[root@linux-server script]# cat x_shift3.sh 
#!/bin/bash
shift
echo "第一个位置参数: $1"
[root@linux-server script]# bash x_shift3.sh 2 3 
第一个位置参数: 3

若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等,则需要用shift把所有参数变成$1
#测试 shift 命令(x_shift.sh) 
[root@linux-server script]# vim x_shift.sh
#!/bin/bash
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#" 
shift
done
执行以上程序: 
[root@linux-server script]# bash x_shift3.sh 1 2 3 4
结果显示如下:
第一个参数为: 1 参数个数为: 4 
第一个参数为: 2 参数个数为: 3 
第一个参数为: 3 参数个数为: 2 
第一个参数为: 4 参数个数为: 1

从上可知 shift 命令每执行一次,变量的个数($#)减一,而变量值提前一位
continue、break、exit
#continue、break、exit命令
Linux脚本中的break continue exit
1.break
结束并退出本次循环
2.continue 
在循环中不执行continue下面的代码(跳出当前条件循环),继续下一轮条件循环
3.exit
直接退出整个脚本,一般返回一个状态码给系统
默认情况下,退出状态码为0,表示正常退出。
非零的退出状态码通常用于指示错误或异常情况,具体含义需要自定义
状态码:
0:表示正常退出。当脚本执行成功且没有发生错误时,可以使用状态码0。
1:通常表示一般性的错误。例如,输入参数有误或未满足某些条件时可以返回1。
2:表示无效或不支持的命令行选项。
127:表示命令未找到,即某个被调用的命令不存在。
128+:表示脚本因收到信号而终止。例如,状态码130表示脚本收到了Ctrl+C的中断信号。
255:表示退出状态码超过了范围(0-255)。

【实例】
[root@localhost script]# vim break.sh
#!/usr/bin/bash
for i in {1..10}
do
if [ $i -eq 7 ];then
        continue
        #break
        #exit 34
else
        echo $i
fi
echo "本次输出结束"
done
echo "脚本结束循环"

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。 

break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
以下脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。 
代码如下:
[root@linux-server script]# vim break.sh
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: " 
read aNum
case $aNum in
        1|2|3|4|5)
        echo "Your number is $aNum!"
        ;;
        *)
        echo "You do not select a number between 1 to 5, game is over!"
        break 
        ;;
esac
done

#将break注释掉观察结果

案例2:continue
continue命令
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
[root@linux-server script]# bash break.sh
 
对上面的例子进行修改:
代码如下:
[root@linux-server script]# vim break1.sh
#!/bin/bash
while :  #默认为真
do
echo -n "Input a number between 1 to 5: " 
read aNum
case $aNum in
        1|2|3|4|5)
        echo "Your number is $aNum!"
        ;;
        *)
        echo "You do not select a number between 1 to 5, game is over!"
        continue 
        ;;
esac
done
[root@linux-server script]# bash break1.sh
#运行代码发现,当输入大于5的数字时,该例中的循环不会结束.

shell 编程-函数

function (功能) 功能函数
​
完成特定功能的代码片段
函数必须先定义才能使用
优点:避免重复的代码
​
定义函数---怎么写函数脚本,如何定义
调用函数--- 怎么使用函数,本地调用,2。通过其他脚本调用
取消函数---- unset func_name
函数传参----和脚本传参类似
​
命名空间:在shell语言中函数的命名空间是函数内和函数外,定义变量是一样的,函数内外不能赋值同样名字的变量
​
#变量:如果在同一个命名空间可以用,如果不再同一个命名空间就不能用
#函数变量使用的范围:默认,函数里的变量会在函数外面生效
#函数变量如果不让在其他空间用使用:local 分开
local  变量名称  #变量只在函数内生效。属于局部变量
​
# vim var.sh
#!/usr/bin/bash
a=10
var() {
        echo $a
        #local a
        a=20
        echo $a
}
var       #调用函数
echo $a
​
#return: 返回结果并退出函数
返回值:return value:#value不能超过0-255,是函数里面函数最后一条执行命令的返回值,默认返回值是由这条命令执行结果确定的.
[root@localhost ~]# vim return.sh
#!/usr/bin/bash
func(){
        echo "hello"
        return 250 #函数返回值
}
func
#echo $?  #返回的是函数的返回值
if [ $? -eq 250 ];then
        echo "成功"
else
        echo "失败"
fi
​
exit:返回结果并退出程序

函数function

函数声明

function_name () {
   list of commands
}

函数名 function_name,这就是你将使用它从其他地方在你的脚本调用。

取消函数

unset function_name #取消函数
[root@linux-server script]# vim func.sh
#!/bin/bash
myfunc(){   #定义函数
echo “This is my first shell function” 
}
myfunc   #函数调用
产生以下执行结果

[root@linux-server script]# bash func.sh 
“This is my first shell function”
函数必须提前定义测试
[root@linux-server script]# vim fun01.sh
#!/bin/bash
fun() {
echo "hello"
}
fun
unset fun   #取消函数
fun
[root@linux-server script]# bash fun01.sh 
hello
fun01.sh: line 7: fun: command not found
函数调用
定义函数脚本
[root@localhost script]# cat a.sh 
#!/usr/bin/bash
check_net() {
        echo "正在检查网络通信"
        ping -c1 www.baidu.com 2&> /dev/null
                if [ $? -eq 0 ];then
                        echo "你的网络是没有问题的"
                else
                        echo "你的网络有问题,请先检查网络"
                        exit 2
                fi
}
check_net   #本地调用
echo "+++++++++++++++++++++++++++++++++++++++++++++"
​
check_yum() {
        echo "正在检查yum源是否可用"
        yum repolist
                if [ $? -eq 0 ];then
                        echo "你的yum源可以正常使用"
                else
                        echo "yum源不能用,请手动配置网络yum源"
                        exit 3
                fi
}
#check_yum
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++"
​
install_nginx() {
#检查网络是否可以上网
check_net
echo "正在配置nginx的yum源"
cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/7/x86_64/
gpgcheck=0
enabled=1
EOF
yum clean all && sleep 2
yum install -y nginx 2&> /dev/null
if [ $? -eq 0 ];then
        echo "nginx install successfull and start nginx"
        sleep 2
        systemctl start nginx
        if [ $? -eq 0 ];then
                echo "nginx started is success,please check port!"
                port=`netstat -lntp | grep nginx | awk '{print $4}' | awk -F ":" '{print $NF}'`
                echo "nginx is port $port"
        else
                echo "nginx 启动失败,请手动检查!"
                exit 4
        fi
else
        echo "nginx install failed!将会自动退出"
        exit 5
fi
}
#install_nginx
函数调用
root@localhost script]# cat b.sh #通过其他脚本调用函数脚本 
#!/usr/bin/bash
while :
do
echo "这是服务器基本检测功能脚本"
        cat <<EOF
++++++++++++++++++++++++++++++++++
+       1. 检查yum源             +
+       2. 检查网络              +
+       3. 安装nginx             +
+       4. 退出                  +
++++++++++++++++++++++++++++++++++
EOF
source ./a.sh  #写你函数脚本的绝对路径,这里指的是执行函数脚本,让它为下面调用函数生效
read -p "请输入你的选项: " num
case $num in
        1)
        check_yum
        ;;
        2)
        check_net
        ;;
        3)
        install_nginx
        ;;
        4)
        exit;;
        *)
        echo "你输入的选项失败请重新输入"
esac
done

函数传参

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 位置参数来进行传参的,$1表示第一个参数,$2表示第二个参数...
示例

[root@linux-server script]# vim fun04.sh
fun() {
        echo $[$1*$2*$3]
}
fun $1 $2 $3
[root@linux-server script]# bash fun04.sh 1 3 5
15

local变量

local 是 Bash shell 中的一个关键字,用于声明局部变量。在 Bash 脚本中,local 主要用于函数内部,以声明仅在该函数作用域内可见的变量。这有助于减少全局变量的数量,提高脚本的可维护性和避免潜在的命名冲突。

声明普通变量:
local variable_name=value
声明数组变量:
local -a array_name=(element1 element2 element3 ...)
关联数组(键值对):
local -A assoc_array_name=( [key1]=value1 [key2]=value2 [key3]=value3 ... )
声明变量并赋默认值:
local variable_name=${variable_name:-default_value}

shell 编程-数组

什么是数组?
数组也是一种变量,常规变量只能保存一个值,数组可以保存多个值
​
#普通数组:只能用整数作为数组的索引--0  下标
#关联数组:可以使用字符串作为数组的索引
数组定义
普通数组定义
# books=( linux shell awk sed ) ---在python中叫列表
        引用: echo ${array_name[index]} 
# echo ${books[0]}
linux
# echo ${books[1]}
shell
# echo ${books[2]}
awk
​
#关联数组需要提前声明
Declare命令:
# declare [-选项]
参数说明:
-a :#定义为数组--array
-A : #定义关联数组
​
例1
declare -A myarry1
# declare -A myarry1
# myarry1=([name]=soso666 [sex]=man [age]=18)
# echo ${myarry1[name]}
soso666
[root@linux-server script]# echo ${myarry1[age]}
18
数组定义方法:
定义方法1:
    # array=( one two three four five six )
    # array1=(`cat /etc/passwd`) #希望是将文件中的每一行作为一个值赋给数组array3
    # array2=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)
​
定义方法2:指定索引赋值 
语法:数组名[index]=变量值
示例
[root@linux-server script]# vim shuzu.sh
#!/bin/bash
NAME[0]="BJ"
NAME[1]="SH"
NAME[2]="SZ"
NAME[3]="GZ"
NAME[4]="HZ"
NAME[5]="ZZ"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
echo "sixth Index: ${NAME[5]}"
​
输出结果
[root@linux-server script]# bash shuzu.sh 
First Index: BJ
Second Index: SH
sixth Index: ZZ
访问数组
当设置任何数组变量时,可以访问它

# aa=(haha heihei baibai)
# echo ${aa[0]}   #访问数组中的第一个元素
# echo ${aa[@]}   #访问数组中所有的元素 等同与echo ${aa[*]} 
# echo ${#aa[@]}  #统计元素的个数 
# echo ${!aa[@]}  #打印数组的所有索引
您可以访问数组中的所有项目通过以下方式之一:

${array_name[*]}
${array_name[@]}
疑难点 shell数组中"*" 和 "@" 区别

关于在shell脚本中数组变量中 “*”跟 “@” 区别
1.*当变量加上"" 会当成一串字符串处理. 
2.@当变量加上"" 依然当做数组处理,在没有加上"" 的情况下效果是一样的数组
[root@linux-server script]# vim test1.sh
#!/usr/bin/env bash
array=(gz cloud 19)
echo "case 1"
for line in "${array[@]}"
do
        echo $line
done
​
echo "case 2"
for line in "${array[*]}"
do
        echo $line
done
​
echo "case 3"
for line in ${array[*]}
do
        echo $line
done
​
echo "case 4"
for line in ${array[@]}
do
        echo $line
done

执行结果

[root@linux-server script]# bash test1.sh 
case 1    使用 ${array[@]} 来迭代数组,每个元素都被正确地输出到新的一行。
gz
cloud
19
case 2    使用 ${array[*]} 迭代数组,所有元素作为一个字符串输出,元素之间没有空格分隔。
gz cloud 19
case 3   没有使用双引号 (") 来包围 ${array[*]}。正确地输出了每个元素到新的一行
gz
cloud
19
case 4   使用 ${array[@]} 来迭代数组,每个元素也被正确地输出到新的一行。
gz
cloud
19

可以看的case2这是因为默认的内部字段分隔符 IFS (Internal Field Separator) 在这种情况下不起作用。
[root@mysql-server script]# vim shuzu.sh
#!/bin/bash
src_ip=(192.168.0.123 192.168.0.124 192.168.0.125 192.168.0.126 192.168.0.127)
#echo ${src_ip[@]}
ip_name=(web-1 web-2 java-1 java-2 mysql-server)
#echo ${ip_name[*]}
for (( i=0; i<${#src_ip[@]}; i++ ))
do
        echo $i-----${src_ip[i]}-----${ip_name[i]}
done

练习

#!/bin/bash
1.检査机器是否可以上网
2.检查yum是否可用
3.安装一些必要工具(vim/wget/net-tools/ntpdate)
4.检查nginx是否安装,
5.替换yum源--nginx
6.安装nginx----yum install-y nginx启动
  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值