Linux初學之函數

function —— 函數


把那些在腳本中重複出現並且沒有任何改變的代碼,封裝起來,在適當的場景中調用執行;

程序員將這種被封裝起來的代碼稱爲功能體,或者叫模塊;



在shell腳本編程中,函數是由若干條shell命令組成的語句塊;通常用於代碼重用和模塊化封裝;


函數裏面的內容和shell程序形式上是一致的;不同之處就是,shell代碼可以直接被執行;而函數中的內容,不能獨立執行,只有被調用的時候才執行;


函數是在shell程序的當前shell中運行的;

bash

bash script_file

function


定義函數:

函數是由兩部分組成:

函數名稱 + 函數體(能夠實現獨立功能的shell語句塊)


語法一:

function func_name {

函數體

}


語法二:

func_name() {

函數體

}

注意:函數名和()之間不能加空白字符;


注意:函數可以在交互式環境下定義,也可以在腳本中定義;


函數的使用

   函數在定義的時候,其函數體中包含的所有命令均不會被執行;只有函數被調用的時候,纔會執行其中的命令語句;


調用方式:通過直接給出函數名稱的方式調用;


有很多的函數是存放於專門用於保存函數的文件中;如果想要調用這樣的文件中保存的函數,使用source命令(.)加載文件,然後再以直接給出函數名稱的方式調用函數;


使用set命令可以查看所有當前shell中生效的函數;

使用unset命令可以撤銷已經定義的函數;


函數的返回值:

   兩種返回值:

函數的執行結果的返回值:

1.在函數體中使用了echo或printf命令輸出的結果;

2.在函數體中某些命令輸出的結果;

函數的狀態返回值:

1.函數中最後一條命令的執行狀態返回值;

2.自定義退出狀態碼:

return [n]

n:0-255 

注意:只要函數在執行時,遇到了return命令,不管函數中的命令語句是否全部執行完成,立刻退出函數;


函數的生命週期:

從被調用開始,到遇到return命令或全部的語句執行完成爲止;


函數的實參

在函數體中,可以使用$1,$2,..位置變量爲函數提供參數;還可以使用$*或$@的方式引用所有位置參數;還可以使用$#計算爲函數傳遞的參數個數;


在調用函數的時候,直接在函數名稱後面以空白字符分隔多個參數即可;比如:func_name arg1 arg2 ...


傳遞給函數參數的位置參數,是調用函數的時候,函數名稱後面的以空白字符分隔的字符串序列;跟腳本的位置參數不是一回事;


變量:

shell中的變量爲弱變量

1.無需事先聲明

2.無需指定變量類型,默認爲字符型


變量分類:

環境變量:

當前shell及子shell

本地變量:

當前shell

局部變量:

local VAR_NAME=VALUE

當前函數體

位置變量

特殊變量


        手動撤銷自己定義或聲明的所有變量;


函數的遞歸調用

簡單來說,就是在函數體中調用函數自身;


階乘:

N!=N*(N-1)!=N*(N-1)*(N-2)!=...=N*(N-1)*(N-2)*...*2*1

#!/bin/bash

# Author: Tianyu.Zhao

#

fact(){

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

    echo 1

  else

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

  fi

}


echo -n "$1!="

fact $1



例子:   斐波那契數列(黃金分隔數列):

1 1 2 3 5 8 13 21 34 55 ...

假設兔子出生一個月之後纔會有繁殖能力:

N=N-1 + N-2


shell代碼:

#!/bin/bash

# Author: Tianyu.Zhao

#

fabonacci(){

  if [ $1 -eq 1 ] ; then

    echo 1

  elif [ $1 -eq 2 ] ; then

    echo 1 

  else

    echo $[$(fabonacci $[$1-1])+$(fabonacci $[$1-2])] 

  fi

}

#列出所有的斐波那契數列的項

for I in `seq 0 $1` ; do

  fabonacci $I

done



例子:   漢諾塔(又稱河內塔)問題是源於印度一個古老傳說。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

利用函數,實現N片盤的漢諾塔的移動步驟

#!/bin/bash

# Author: Tianyu.Zhao

#

step=0

move(){

let step++

echo "$step:  move disk $1 $2 -----> $3"

}

hanoi(){

if [ $1 -eq 1 ];then

move  $1 $2 $4

else

hanoi "$[$1-1]" $2 $4 $3

move $1 $2 $4

hanoi "$[$1-1]" $3 $2 $4

fi

}


hanoi $1 A B C


文件abc.txt的內容如下:

2,3,4,5,6

B,c,d,e,f

6,7,8,9,10

f,g,h,i,j

寫一個腳本,利用任一循環結構,輸出每一行的第二個和第四個字符(以逗號分隔)


回顧:

shell腳本編程之函數


練習:

寫一個腳本:

1.允許用戶通過命令行傳遞參數,實現用戶賬戶的管理;

2.如果給出-a|--add選項,就創建該選項後面的用戶賬戶;

3.如果給出-d|--del選項,就刪除該選項後面的用戶賬戶;

4.如果用戶給出-v|--verbose選項, 就顯示刪除或創建用戶的信息;

5.如果用戶給出-h|--help選項,就顯示幫助信息,並且以0作爲退出狀態碼退出腳本的運行;

6.如果用戶給出其他選項,顯示幫助信息,並以5作爲退出狀態碼鬼畜腳本的運行;


#!/bin/bash

#Author: Link

#Description: administrate users

#5: no enough args

#6: error args

#

DEBUG=0

ADDUSER=0

DEUSER=0


usage(){

echo "Usage: $(basename $0) -a|--add user1,user2,... | -d|--del user1,user2,... | [-v|-verbose] | [-h|--help]"

echo

  echo "Options: "

  echo -e "  -a, --add\vCreate user from list."

  echo -e "  -d, --del\vDelete user from list."

  echo -e "  -v, --verbose\vDisplay infomation for your operating."

  echo -e "  -h, --help\vDisplay this menu."

}


createuser() {

ADDUSER_LIST=$(echo $1 | tr ',' ' ')

for I in $ADDUSER_LIST ; do

if id $I &> /dev/null ; then

[ $DEBUG -eq 1 ] && echo "$I exists."

else

useradd $I &> /dev/null

echo $I | passwd --stdin $I &> /dev/null

[ $DEBUG -eq 1 ] && echo "Create $I successfully."

fi

done

}


deleteuser() {

DELUSER_LIST=$(echo $1 | tr ',' ' ')

for J in $DELUSER_LIST ; do

if id $J &> /dev/null ; then

userdel -r $J &> /dev/null

[ $DEBUG -eq 1 ] && echo "Delete $J finished."

else

[ $DEBUG -eq 1 ] && echo "$I not exists."

fi

done

}


if [ $# -le 0 ] ; then

usage

exit 5

fi


while [ $# -ne 0 ] ; do

case $1 in

-h|--help)

usage

exit

;;

-v|--verbose)

DEBUG=1

shift

;;

-a|--add)

ADDUSER=1

ALIST=$2

shift 2

;;

-d|--del)

DELUSER=1

DLIST=$2

shift 2

;;

*)

usage

exit 6

;;

esac

done


if [ $ADDUSER -eq 1 ] ; then

createuser $ALIST

fi


if [ $DELUSER -eq 1 ] ; then

deleteuser $DLIST

fi


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章