1.函数的定义和语法,查看及删除
函数由两部分组成:函数名和函数体
语法一:
f_name (){ ...函数体... }
语法二:
function f_name { ...函数体... }
语法三:
function f_name () { ...函数体... }
示例
[root@localhost init.d]# func1(){ echo func1; } [root@localhost init.d]# func1 func1 [root@localhost init.d]# function func2(){ echo func2; } [root@localhost init.d]# func2 func2 [root@localhost init.d]# function func3(){ > echo func3 > } [root@localhost init.d]# func3 func3 [root@localhost init.d]# declare -f func1 () { echo func1 } func2 () { echo func2 } func3 () { echo func3 } [root@localhost init.d]# unset func{1,2,3} [root@localhost init.d]# declare -f [root@localhost init.d]# [root@localhost init.d]# function func4 { > echo func4 > } [root@localhost init.d]# func4 func4 [root@localhost init.d]# set|tail -l UID=0 USER=root XDG_RUNTIME_DIR=/run/user/0 XDG_SESSION_ID=12 _= colors=/root/.dircolors func4 () { echo func4 }
2.函数使用
1.函数的定义和使用
可在交互式环境下定义函数
可将函数放在脚本文件中作为它的一部分
可放在只包含函数的单独文件中
调用:函数只有被调用才会执行
调用:给定函数名
函数名出现的地方,会被自动替换为函数代码
函数的生命周期:被调用时创建,返回时终止
2. 函数返回值
函数有两种返回值:
函数的执行结果返回值:
(1) 使用echo等命令进行输出
(2) 函数体中调用命令的输出结果
函数的退出状态码:
(1) 默认取决于函数中执行的最后一条命令的退出状态码
(2) 自定义退出状态码,其格式为:
return 从函数中返回,用最后状态命令决定返回值
return 0 无错误返回。
return 1-255 有错误返回
3.在脚本中定义及使用函数
函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它
后才能使用
调用函数仅使用其函数名即可
示例:
cat func1
#!/bin/bash # func1 hello() { echo "Hello there today's date is `date +%F`" } echo "now going to the function hello" hello echo “back from the function”
环境函数
使子进程也可使用
声明:export -f function_name
查看:export -f 或 declare -xf
3.实例
1.函数名与外部命令,内部命令,别名的优先级
[root@localhost function]# hostname () { echo hostname function; } [root@localhost function]# hostname hostname function [root@localhost function]# history () { echo history function; } [root@localhost function]# history history function [root@localhost function]# alias ho=hostname [root@localhost function]# ho (){ echo ho functions; } [root@localhost function]# ho ho functions
2.函数中的变量
函数变量
变量作用域:
环境变量:当前shell和子shell有效
本地变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数
局部变量:函数的生命周期;函数结束时变量被自动销毁
注意:如果函数中有局部变量,如果其名称同本地变量,使 用局部变量
在函数中定义局部变量的方法
local NAME=VALUE
[root@localhost ~]# func1 (){ name=whr ;echo "func1:$name"; } [root@localhost ~]# func1 func1:whr [root@localhost ~]# echo $name whr [root@localhost ~]# unset func1 [root@localhost ~]# func1 (){ local name=whr ;echo "func1:$name"; } [root@localhost ~]# func1 func1:whr [root@localhost ~]# echo $name whr
3.位置参数
[root@localhost ~]# func1(){ echo args:$1;echo args:$2;echo args:$@; } [root@localhost ~]# func1 1 2 3 4 args:1 args:2 args:1 2 3 4 [root@localhost ~]# unset func1 [root@localhost ~]# func1(){ echo args:$1;echo args:$2;echo args:$#; } [root@localhost ~]# func1 1 2 3 4 args:1 args:2 args:4
4.函数递归
函数递归:
函数直接或间接调用自身
注意递归层数
1.整数的阶乘
#!/bin/bash [[ $1 =~ [^[:digit:]]+ ]] && { echo "the $1 is not natural number" ;exit; } digui () { if [ $1 -le 1 ] ;then echo 1 else echo $[$1*$(digui $[$1-1])] fi } digui $1
以下为脚本的执行结果
[root@localhost ~]# bash -x digui1.sh 5 + [[ 5 =~ [^[:digit:]]+ ]] + digui 5 + '[' 5 -le 1 ']' ++ digui 4 ++ '[' 4 -le 1 ']' +++ digui 3 +++ '[' 3 -le 1 ']' ++++ digui 2 ++++ '[' 2 -le 1 ']' +++++ digui 1 +++++ '[' 1 -le 1 ']' +++++ echo 1 ++++ echo 2 +++ echo 6 ++ echo 24 + echo 120 120
2.生成斐波那契数列
#!/bin/bash #!/bin/bash feibo(){ #函数递归调用生成斐波那契数列 if [ $1 -eq 1 ];then echo 0 elif [ $1 -eq 2 ];then echo 1 else echo $[$(feibo $[$1-1])+$(feibo $[$1-2])] fi } number(){ #按斐波那契数列的个数生成 while true;do read -p "Please input a number(>2):" n if [ -z $n ];then : elif [[ $n =~ [^[:digit:]]+ ]];then echo "you input $n is not number" elif [ $n -ge 3 ];then break else : fi done echo 0 echo 1 for i in `seq 3 $n`;do m=$i feibo $i done } maxinum() { #按第n个斐波那契数列的数值大小生成 while true;do read -p "Please input the display max number(should great than 1):" NUM if [ -z $NUM ];then : elif [[ $NUM =~ [^[:digit:]]+ ]];then echo "you input $n is not number" elif [ $NUM -ge 1 ];then break else : fi done echo 0 echo 1 i=0 #测试时i没有赋值脚本也正常 while true;do i=$[i+1] feibo $i if [ -z $NUM ];then : elif [ `feibo $i` -gt $NUM ];then exit fi done } cat<<EOF ****************************************************************** * Please choose create The Fibonacci sequence mode: * * * * 1.按斐波那契数列的个数生成 * * 2.按第n个斐波那契数列的数值大小生成 * * 3.退出 * * * ****************************************************************** EOF read -p "Please choose create The Fibonacci sequence mode:" mode case $mode in 1) number #调用按斐波那契数列的个数生成的函数 ;; 2) maxinum #调用按第n个斐波那契数列的数值大小生成的函数 ;; *) exit #输入的是其他的内容就退出 ;; esac
脚本运行结果如下
[root@localhost ~]# bash feibonaqie.sh ****************************************************************** * Please choose create The Fibonacci sequence mode: * * * * 1.按斐波那契数列的个数生成 * * 2.按第n个斐波那契数列的数值大小生成 * * 3.退出 * * * ****************************************************************** Please choose create The Fibonacci sequence mode:1 Please input a number(>2):5 0 1 1 2 3 [root@localhost ~]# bash feibonaqie.sh ****************************************************************** * Please choose create The Fibonacci sequence mode: * * * * 1.按斐波那契数列的个数生成 * * 2.按第n个斐波那契数列的数值大小生成 * * 3.退出 * * * ****************************************************************** Please choose create The Fibonacci sequence mode:2 Please input the display max number(great than 1):46 0 1 1 2 3 5 8 13 21 34 55 [root@localhost ~]# bash feibonaqie.sh ****************************************************************** * Please choose create The Fibonacci sequence mode: * * * * 1.按斐波那契数列的个数生成 * * 2.按第n个斐波那契数列的数值大小生成 * * 3.退出 * * * ****************************************************************** Please choose create The Fibonacci sequence mode:3 [root@localhost ~]#
5.fork炸弹
fork炸弹是一种恶意程序,它的内部是一个不断在fork进程的无限循环,实质是一个简单的递归程序。由于程序是递归的,如果没有任何限制,这会导致这个简单的程序迅速耗尽系统里面的所有资源
函数实现
:(){ :|:& };: bomb() { bomb | bomb & }; bomb
脚本实现
cat Bomb.sh
#!/bin/bash ./$0|./$0&
没有帐号? 立即注册