Shell 函数的作用域 数组遍历

本篇内容:

  • 函数
    • 函数(重点:作用域)
    • 数组
    • 信号处理

函数

一 函数介绍

# 什么是函数?
    具备某一功能的工具=》函数
    事先准备工具的过程=》函数的定义
    遇到应用场景拿来就用=》函数的调用

# 为何要用函数?
    没有引入函数前,遇到重复使用某一个功能的地方,只能复制黏贴实现该功能的代码,这会导致
    1、代码冗余=》程序组织结构不清晰,可读性差
    2、如果该功能的代码需要修改,那么需要找到所有黏贴这段代码的地方进行修改=》可扩展性差

# 如何用函数?
    函数的使用应该遵循一个原则:先定义、再调用

二 函数的基本使用

1、先定义

# 格式1: 推荐
function 函数的名字() {
    命令1
    命令2
    命令3
    ...
}

# 格式2
function 函数的名字 {
    命令1
    命令2
    命令3
    ...
}

# 格式3
函数的名字() {
    命令1
    命令2
    命令3
    ...
}

2、后调用

函数的名字

示例

[root@egon day06]# ./1.sh 
函数f1调用了
函数f2调用了
函数f3调用了
[root@egon day06]# cat 1.sh 
#!/bin/bash

function f1() {
    echo '函数f1调用了'
}

function f2 {
    echo '函数f2调用了'
}

f3() {
    echo '函数f3调用了'
}


f1
f2
f3


[root@egon day06]# ./1.sh 
函数f1调用了
函数f2调用了
函数f3调用了
[root@egon day06]# 

三 函数的参数

可以把函数想象成一座工厂
    函数=》工厂
    函数体代码=》流水线
    调用者为函数传递的参数=》为工厂运送的原材料
    函数的返回值=》流水线加工的产品

ps
函数是否需要参数,取决于函数体代码是否需要

示例

#!/bin/bash

function add() {
    # [ # -ne 2 ] && echo "必须为函数传入两个参数" && exit
    [# -ne 2 ] && echo "必须为函数传入两个参数" && return
    res=[1 + 2 ]
    echo "10+11=res"
}

add 10 11 22

echo "=============>"

四 函数的返回值

在shell语言中return返回的是函数运行的状态,而且只能返回值int型(0-255)

return是函数结束的标志,函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的当做函数的运行状态返回

#!/bin/bash

function test() {
    echo "hello"
    return 0
    echo "world"
    return 255
    echo "hahaha"
    return 256
}

test
echo $?

ps:如果函数体代码没有return,那么函数的运行状态默认就是函数体代码最后一条命令的运行状态

五 作用域

#1 什么是作用域
作用域即作用域范围,具体是值变量的作用域范围
何为变量的作用域范围:定义一个变量,都可以在什么地方访问到

#2 为何要有作用域
为了区分变量查找范围的优先级,避免冲突

1、局部作用域=》函数内用local关键字声明的变量=》只能在函数内访问

#!/bin/bash

function f1() {
    local x=111
    echo x  # 在函数内找
}
f1
echox  # 在函数外找

2、全局作用域=》在当前进程内声明的变量=》可以在当前进程的任意位置访问到

#!/bin/bash

y=222  # 全局变量

function f2() {
    echo y
}

f2

echoy

ps:只要没有被local声明的变量,都是全局变量,都是在整个进程有效

#!/bin/bash

function f2() {
    z=333
    echo z
}

f2

echoz

3、环境变量

export声明的变量称之为环境变量,环境变量的范围:父进程定义的环境变量,子子孙孙进程都可以看到

注意:

​ 1、传子不传爹

​ 2、没有父子关系export无效

4、登录shell与非登陆shell

# 环境变量的使用细节
/etc.bashrc
/etc/profile.d/

每次起bash进程都会执行上面2个文件.如果把定义变量写到上面两个文件里, 可能会使用更多的内存.

# 如果写到/etc/profile下,相当于在第一个父进程中就定义了环境变量. 这样所有的子进程都可以使用这个定义的变量,而不用每次都执行定义. 节省了内存空间.

数组

一 数组介绍

#1、数组
一组数据的集合,与整型、浮点型、字符串型不同的是一个数组可以同时存放多个值

#2、为何要用数组
把相关的变量归置到一起,程序的组织结构更清晰

#3、如何用数组

二 数组的使用

1、定义

# 方式一
array=(1.3 111 "aa")

# 方式二
array=([0]=1.3 [1]=111 [2]="aaa")

ps: 可以换顺序,也可空着来
array=([2]="aaa" [0]=1111111)

# 方式三
[root@egon ~]# array[0]=1.3
[root@egon ~]# array[2]="aaa"

# 方式四:
[root@egon ~]# array=(`ls .`)

[root@egon ~]# echo {array[0]}
anaconda-ks.cfg
[root@egon ~]# echo{array[1]}
check_httpd.sh
[root@egon ~]# echo ${array[2]}

# 方式五 (普通数组用-a 关联数组用-A)
declare -a stu_name=([0]="aa" [1]="Tom")

2、使用

array=(1.3 111 "aa")
# 1、查看数组元素
echo {array[0]}
echo{array[-1]}

echo {array[*]}  # 查看数组内所有元素
echo{array[@]}  # 查看数组内所有元素

echo {#array[*]}  # 查看数组内元素的个数
4

[root@egon ~]# declare -a  # 查看声明过的数组
# 2、修改和添加
array[0]=3.6
array[5]=3333

# 3、删除
删除整个数组
unset array

删除某一个
[root@egon ~]# array=(1.3 111 "aa")
[root@egon ~]# echo{array[*]}
1.3 111 aa
[root@egon ~]# 
[root@egon ~]# unset array[1]
[root@egon ~]# echo {array[*]}
1.3 aa
[root@egon ~]# 

# 4、截取(了解)
指定索引截取
[root@egon ~]# array=(egon 18 male IT 1.80 11 22 33)
[root@egon ~]# echo{array[*]:3:2}
IT 1.80
[root@egon ~]# 

指定元素删除(不改变原数组)
[root@zabbix ~]# array=(one two three four five fire)
[root@zabbix ~]# echo {array[*]#one}
two three four five fire
[root@zabbix ~]# echo{array[*]#five} 
one two three four fire
[root@zabbix ~]# echo {array[*]#f*e} 
one two three four


# 5、替换(了解)
[root@egon ~]# array=(one two three four five fire)
[root@egon ~]# echo{array[*]/f*e/111}
one two three four 111 111

三 关联数组

上面介绍的索引对应元素的数组称之为普通数组
关联数组指的是可以指定key对应value

[root@egon ~]# declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")
[root@egon ~]# echo {array["age"]}
18

# 查询所有数组 *
[root@egon ~]# echo{array[*]}
male egon 18

# 查询所有数组 @
[root@egon ~]# echo {array[@]}
male egon 18

# 查询个数
[root@egon ~]# echo{#array[@]}
3

四 数组的遍历

遍历普通数组的方式1:取值

array=(one two three four five fire)

for i in {array[*]}
do
    echoi
done

遍历普通数组的方式2:取索引,进而取值

# {!array[*]} 对应数组中的索引

array=(one two three four five fire)

for i in{!array[*]}
do
    echo i{array[$i]}  # 获取索引及其对应的元素
done

遍历关联数组的方式1: 取值

declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")

for x in {array[*]}
do
   echox
done

遍历关联数组的方式2: 取key,进而取value

declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")

for k in {!array[*]}
do
   echok {array[k]}
done

练习:基于关联数组统计/etc/passwd文件中不同种类shell的个数

[root@egon day06]# cat 11.sh 
#!/bin/bash

declare -A shell_count

while read line    # 读取一行
do
    s=`echo line|awk -F: '{print7}'`
    let shell_count[s]++
done{!shell_count[*]}
do
   echo k{shell_count[$k]}
done
[root@egon day06]# ./11.sh 
/sbin/nologin 21
/bin/sync 1
/bin/bash 2
/sbin/shutdown 1
/sbin/halt 1

案例: 红绿灯交替闪烁

#!/bin/bash
n=1
while :
do
#交替改变n的0和1状态
    [ n -eq 0 ] && n=1 || n=0    if [n -eq 1 ];then
        echo -e "\033[31m 红 \033[0m"
    else
        echo -e "\033[32m 绿 \033[0m"
    fi
    sleep 1
    clear
done

#交替改变n的0和1状态(常用)
[ $n -eq 0 ] && n=1 || n=0 

Copyright © 2009 - Now . XPBag.com . All rights Reserved.
夜心的小站 » Shell 函数的作用域 数组遍历

提供最优质的资源集合

立即查看 了解详情