shell腳本基礎編程第四篇
本章主要內容:函數
函數
function:
function 名稱 { 命令 ; } 或 name () { 命令 ;
}
定義 shell 函數。
創建一個以 NAME 為名的 shell
函數。當作為一個簡單的命令啟用時,
NAME 函數執行調用 shell 的上下文中的 COMMANDs 命令。當
NAME
被啟用時,參數作為 $1…$n 被傳遞給函數,函數的名字儲存在變量
$FUNCNAME
中。
函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程
與shell程序形式上是相似的,不同的是他不是一個單的進程,
不能獨立運行,而是shell程序的 一 部分。
函數由兩部分組成:函數名和函數體
語法:
function f_name
{
…函數體..
}
語法:
f_name()
{
…函數體…
}
函數的定義和使用:
可在交互式環境下定義函數
可將函數放在腳本文件中作為它的一部分
可放在只包含函數的單獨文件中
調用:函數只有被調用才會執行
調用:給定的函數名
函數名出現的地方,會被自動替換為函數代碼
函數的生命周期:被調用時創建返回時終止
函數返回值:
函數的執行結果返回值:
使用echo或printf命令進行輸出
函數體中調用命令的輸出結果
函數的退出狀態碼:
默認取決與函數中執行的最后一條命令的退出狀態碼
自定義退出狀態碼:
return
從函數中返回,用最后狀態命令決定返回值
return 0
沒有錯誤返回
return 1-255 有錯誤返回
==========================================================================
命令行舉例,交互式環境下舉例
[root@Compro ~]# function fun1(){ echo "xiaomag";}
在一行里面要加上;分號
[root@Compro ~]# fun1
xiaomag
定義函數名稱為fun1,函數體為輸出xiaomag;
然后直接輸入fun1函數名,輸出的內容為xiaomag
==========================================================================
shell腳本間簡單舉例
[root@Compro
~]# vim fun2.sh
#!/bin/bash
#
#user:Compro
#簡單定義函數名稱,函數體可以是命令,下面看下幾個簡單的命令
fun2(){
這個算是在腳本中嵌入了函數
who
pwd
函數一般在文件的前面;調用文件的前面;
ifconfig
如果把下面的echo放在最前面,會導致不能調用這個函數;
ls
hostname
執行后會顯示這幾條命令的結果返回值
echo "執行函數fun2結果"
當所有函數執行結束后,顯示打新輸入一句話;也可以說是返回值
}
echo "執行函數fun2開始"
在這個函數體執行的開始輸出顯示
fun2
echo "執行函數fun2結束" 執行上面結果結束后最后顯示
函數在使用前必須定義,因此應該將函數定義放在腳本的開始 ,
直到shel首次發現函數體后才能使用;調用函數體僅使用定義好的函數名就可以。
注意:在腳本里面定義的函數,不能在命令行下單獨使用,因為不在一個shell進程,兩邊不想干
==========================================================================
set可以產看顯示定義的變量。以及函數;
該定義的函數將一直保留到用戶從系統退出,或執行了
unset fun1 取消函數定義
函數優先級:
別名
函數
內部
外部
使用函數文件:
可以將經常使用的函數存入函數文件,然后將函數文件載入shell中。
文件名可任意的選取,但是最好與相關任務有某種聯系。
例如:functions.main
==========================================================================[root@Compro
~]# vim funs 創建函數文件
#/bin/bash
fun3(){
函數名
echo "xiaomag"
函數體
}
funn4(){ 函數名
edho
"xiaomage" 函數體
} 可以定義多個函數
==========================================================================
當函數文件定義好以后,需要加載到當前shell才能使用,就可以在命令行或腳本中調用函數,
可以使用set命令查看并檢查所有定義的函數,
其輸出列表包括已經載入shell的所有函數。
加載函數文件到當前shell:.
filename 或者 source filename
注意:.點 空格 文件名 這里的文件名要帶正確路徑
執行shell函數:
[root@Compro ~]# fun3
xiaomag
[root@Compro ~]#
fun4
xiaomage
==========================================================================
若是要改動函數,首先用unset命令從shell中刪除函數,改動完畢后,才重新載入此文件。
現在對函數做一些改動。首先刪除函數,使其對shell不可用。使用unset命令完成此功能
命令格式為:unset
函數名稱
[root@Compro ~]# unset fun4 這樣shell中 set就沒有個這函數了
==========================================================================
在shell腳本中調用函數文件中的函數
[root@Compro ~]#
vim testfuns.sh 腳本
#/bin/bash
source funs
在腳本里面調用funs函數文件中的函數;如果函數文件要是跟這個腳本不在一個路徑下,要寫清楚路徑
fun3
函數名
fun4 函數名
==========================================================================
函數參數:
傳遞參數給函數:調用函數時,在函數名后面以空白分隔給定參數列表即可;
例如 fun1 變量1 變量2
…
在函數體當中可使用$1 $2 … 調用這些參數;還可以使用$@,$*,$# 等特殊變量
函數變量:
環境變量:當前shell和子shell有效
本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程,
因此,本地變量的作用范圍是當前shell腳本程序文件,包括腳本中的函數
局部變量:函數的生命周期;函數結束時變量自動銷毀
注意:如果函數中有局部變量,如果其名稱同本地變量,使用局部變量。
在函數中定義局部變量的方法:
local 變量名=變量值 函數內部有效。不加local是本地變量,加上是局部變量
函數遞歸:
函數直接或間接調用自身
注意遞歸層數
舉例
fun (){echo fun;fun;}
死循環,直到一定的程度會退出當前shell終端
fun () { let i++;echo $i;fun;}
遞增i循環。直到當前系統資源耗盡退出當前shell終端
10!=10*9!=10*9*8!=10*9*8*7!=…
n!=1*2*3….*n
(n-1)!=1*2*3….*(n-1)*n=n!
fun(
echo fun n-1 *
n
)
==========================================================================
vim
fact.sh
#/bin/bash
#
#user:Compro
fact(){ 階乘函數
if [ $1 -eq 0
-o $1 -eq 1 ];then調用 $1等于0 0的階乘等于1 或者 $1等1 1的階乘是1
echo
1如過給的數值是0或者是1就打印1
else如果給的不是0也不是0
echo "$[ $1*` fact
$[$1-1]`]"$1*調用函數自己$1-1的值 它們的階乘
fi
}
fact $1通過調用函數的值$1
==========================================================================
執行結果
[root@Compro ~]# bash fact.sh
1
1
[root@Compro ~]# bash fact.sh 2
2
[root@Compro ~]# bash fact.sh
3
6
[root@Compro ~]# bash fact.sh 4
24
[root@Compro ~]# bash -x
fact.sh 4
+ fact 4
+ '[' 4 -eq 0 -o 4 -eq 1 ']'
++ fact 3
++ '[' 3
-eq 0 -o 3 -eq 1 ']'
+++ fact 2
+++ '[' 2 -eq 0 -o 2 -eq 1 ']'
++++
fact 1
++++ '[' 1 -eq 0 -o 1 -eq 1 ']'
++++ echo 1
+++ echo 2
++
echo 6
+ echo 24
24
原創文章,作者:小馬哥,如若轉載,請注明出處:http://www.www58058.com/39049