shell编程之函数
2018-05-13 15:41:06    98    0    0
wang2020

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&​

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


上一篇: shell编程之expect用法

下一篇: shell编程之字符串处理

98 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航