linux基础篇-函数基础

一 函数介绍

 函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程,先定义,后使用。

 它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

 函数和shell比较相似,区别:Shell程序在子Shell中运行而Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改。


二 定义函数

  函数由两部分组成:函数名和函数体

  help function

  语法一:

  f_name (){

  ...函数体...

  }

  语法二:

  function f_name {

  ...函数体...

  }

  语法三:

 function f_name () {

  ...函数体...

  }

函数的定义和使用:

 可在交互式环境下定义函数

 可将函数放在脚本文件中作为它的一部分

 可放在只包含函数的单独文件中

调用:函数只有被调用才会执行调用:给定函数名函数名出现的地方,会被自动替换为函数代码

函数的生命周期:被调用时创建,返回时终止

用 {   } 括起来的被称为匿名函数 

declare -f 运行函数体

unset function 释放函数

函数变量

变量作用域:

 环境变量:当前shell和子shell有效

 本地变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本程序文件,包括  脚本中的函数局部变量: 函数的生命周期;函数结束时变量被自动销毁

注意:如果函数中有局部变量,如果其名称同本地变量,使用局部变量

在函数中定义局部变量的方法

  local NAME=VALUE  :用local 限制成局部变量。

   

三 环境函数

使子进程也可使用

声明:export -f function_name   声明环境函数,可以传给子进程使用。

查看:export -f 或 declare -xf     

函数使用

 函数的定义和使用:

  可在交互式环境下定义函数。

  可将函数放在脚本文件中作为它的一部分。

  可放在只包含函数的单独文件中。

 调用:函数只有被调用才会执行调用:给定函数名函数名出现的地方,会被自动替换为函数代码。

 函数的生命周期:被调用时创建,返回时终止。


四 载入函数

函数文件已创建好后,要将它载入shell

定位函数文件并载入shell的格式

   . filename 或 source filename

   注意:此即<点> <空格> <文件名>这里的文件名要带正确路径

示例:上例中的函数,可使用如下命令:. functions.main


五 删除shell函数

 现在对函数做一些改动后,需要先删除函数,使其对shell不可用。使用unset命令完成删除函数

 命令格式为:unset function_name

 示例:

  unset findit

  再键入set命令,函数将不再显示

 环境函数

  使子进程也可使用

  声明:export -f function_name

  查看:export -f 或 declare -xf


六 函数参数

 函数可以接受参数:

  传递参数给函数:调用函数时,在函数名后面以空白分隔给定参数列表即可;

  例如“testfunc arg1 arg2 ...”

  在函数体中当中,可使用$1, $2, ...调用这些参数;还可以使用$@, $*, $#等特殊变量


七 函数变量

 变量作用域:

  环境变量:当前shell和子shell有效

  本地变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数

  局部变量:函数的生命周期;函数结束时变量被自动销毁

 注意:如果函数中有局部变量,如果其名称同本地变量,使 用局部变量

 在函数中定义局部变量的方法

  local NAME=VALUE


八 函数递归示例

 函数递归: 函数直接或间接调用自身注意递归层数

 递归实例:

  阶乘是基斯顿·卡曼于 1808 年发明的运算符号,是数学术语

  一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1,自然数n的阶乘写作n!

  n!=1×2×3×...×n

  阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n

  n!=n(n-1)(n-2)...1

  n(n-1)! = n(n-1)(n-2)!

 函数递归示例

  示例:fact.sh

   #!/bin/bash

   fact() {

    if [ $1 -eq 0 -o $1 -eq 1 ]; then

        echo 1

        else

        echo $[$1*$(fact $[$1-1])]

    fi

    }

    fact $1


九 信号捕捉trap

 trap '触发指令' 信号: 自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作。

 trap '' 信号:忽略信号的操作。

 trap '-' 信号:恢复原信号的操作。

 trap -p:列出自定义信号操作。


十 数组

 变量:存储单个元素的内存空间

 数组:存储多个元素的连续的内存空间,相当于多个变量的集合

 数组名和索引

  索引:编号从0开始,属于数值索引

  注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,

  bash4.0版本之后开始支持

  bash的数组支持稀疏格式(索引不连续)

 1声明数组:

  declare -a ARRAY_NAME:普通数组

  declare -A ARRAY_NAME: 关联数组

  注意:两者不可相互转换

 2数组赋值

 数组元素的赋值

  (1) 一次只赋值一个元素

   ARRAY_NAME[INDEX]=VALUE

   weekdays[0]="Sunday"

   weekdays[4]="Thursday"

 (2) 一次赋值全部元素

  ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)

 (3) 只赋值特定元素

  ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)

 (4) 交互式数组值对赋值

  read -a ARRAY

  显示所有数组:declare -a

 3 引用数组

 引用数组元素:${ARRAY_NAME[INDEX]}注意:省略[INDEX]表示引用下标为0的元素

 引用数组所有元素:

  ${ARRAY_NAME[*]}

  ${ARRAY_NAME[@]}

 数组的长度(数组中元素的个数):

  ${#ARRAY_NAME[*]}

  ${#ARRAY_NAME[@]}

 删除数组中的某元素:导致稀疏格式

  unset ARRAY[INDEX]

 删除整个数组: 

  unset ARRAY

 4 数组数据处理

 引用数组中的元素:

  数组切片:${ARRAY[@]:offset:number}

  offset: 要跳过的元素个数

  number: 要取出的元素个数

  取偏移量之后的所有元素

  ${ARRAY[@]:offset}

 向数组中追加元素:

  ARRAY[${#ARRAY[*]}]=value

 关联数组:

  declare -A ARRAY_NAME

  ARRAY_NAME=([idx_name1]='val1' [idx_name2]='val2‘...)

  注意:关联数组必须先声明再调用

 5 字符串切片

  ${#var}:返回字符串变量var的长度

  ${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)

  ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

  ${var: -length}:取字符串的最右侧几个字符,注意:冒号后必须有一空白字符

  ${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容

  ${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格

6 字符串处理

 基于模式取子串

  ${var#*word}:其中word可以是指定的任意字符:功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符之   间的所有字符.

  ${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容.

 示例:

  file=“var/log/messages”

  echo ${file#*/}         结果 :log/messages

  echo ${file##*/}       结果 :messages

 ${var%word*}:其中word可以是指定的任意字符

  功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符之间的所有字符

  file="/var/log/messages"

  echo  ${file%/*}  结果: /var/log

 ${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符;

 示例:

  url=http://www.magedu.com:80

  echo ${url##*:}   结果 :80

  echo ${url%%:*}  结果: http

 查找替换:

  ${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之

  ${var//pattern/substr}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之

  ${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之

  ${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之

 查找并删除

  ${var/pattern}:删除var表示的字符串中第一次被pattern匹配到的字符串

  ${var//pattern}:删除var表示的字符串中所有被pattern匹配到的字符串

  ${var/#pattern}:删除var表示的字符串中所有以pattern为行首匹配到的字符串

  ${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串

 字符大小写转换

  ${var^^}:把var中的所有小写字母转换为大写

  ${var,,}:把var中的所有大写字母转换为小写



猜你喜欢

转载自blog.51cto.com/13498416/2172877