shell腳本-函數


shell腳本-函數

函數介紹

	函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程。
	它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell 程序的一部分。
	函數和shell程序比較相似,區別在於:
		Shell 程序在子Shell中運行
		而Shell函數在當前Shell中運行。因此在當前Shell中,函數可以對shell 中變量進行修改

定義函數

	函數由兩部分組成,函數名和函數體。
	/etc/init.d/functions中提供了些系統設定好的函數,可以直接調用。
	help function
		function name { COMMANDS ; } 
		or 
		name () { COMMANDS ; }
		語法一:
			function f_name {
				... 函數體...
			}
		語法二:
			function f_name() {
				... 函數體...
			}
		語法三:
			f_name() {
				... 函數體...
			}
	定義方式:
		可在交互式環境下定義函數
		可在腳本中定義函數

函數使用

	可將函數放在腳本文件中使用
	可放在只包含函數的單獨文件中使用
	可在交互式環境中使用
	函數調用:
		函數只有被調用才會執行
		調用給定函數名,函數名出現的地方,會被自動替換為函數代碼
	函數的生命周期
		被調用時創建,返回時終止

交互式環境下定義和使用函數

	示例:在命令行中直接進行
		dir() {
		> ls -l
		> }
	定義該函數后,使用$dir,其顯示結果同ls -l的作用相同
	該dir函數將會一直保留到用戶從其他退出,或者執行unset dir命令。

腳本中定義和使用函數

	函數在使用前須先被定義,所以在腳本中使用函數是,必須在腳本開始前定義函數。
	調用函數僅使用其函數名即可
	示例:
		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"

函數返回值

	函數有兩種返回值,分別為執行結果的返回值和退出狀態碼。
	函數的執行結果返回值:
		使用echo 等命令進行輸出
		函數體中調用命令的輸出結果
	函數的退出狀態碼:
		默認取決於函數中執行的最后一條命令的退出狀態碼
		自定義退出狀態碼,其格式為:
			return 從函數中返回,用最后狀態命令決定返回值
				return 0 無錯誤返回。
				return 1-255 有錯誤返回
				

函數文件

	可以將經常使用的函數存入函數文件,然后將函數文件載入shell。
	文件名可任意選取,但最好與相關任務有某種聯系,如functions.main
	一旦函數文件載入shell ,就可以在命令行或腳本中調用函數。
	可以使用set或declar -f 命令查看所有定義的函數,其輸出列表包括已經載入shell 的所有函數。
	創建函數文件
		函數文件示例:
			cat functions.main
			#!/bin/bash
			#functions.main
			findit()
			{
				if [ $# -lt 1 ] ; then
					echo "Usage:findit file"
					return 1
				fi
				find / -name $1 –print
			}
		函數中使用return 來返回值,exit用於腳本
	載入函數
		函數文件已創建好后,要將它載入shell.
		定位函數文件並載入shell的格式:
			. | source filename
			注意:此即< 點> < 空格> < 文件名>,這里的文件名要帶正確路徑.
		示例:
			.|source functions.main
	載入函數稱為環境函數
		子進程也可使用
		使用export -f function_name來載入成為環境函數
		
	檢查查看載入的函數
		使用set 或者 declar -f 命令檢查函數是否已載入。
	執行shell函數
		要執行函數,簡單地鍵入函數名即可。
	改動shell函數
		若要改動函數,首先用unset 命令從shell 中刪除函數,改動完畢后,再重新載入此文件。
	刪除shell函數
		使用unset 命令完成刪除函數。
		unset function_name

函數參數

	函數可接收參數。
	傳遞參數給函數:
		調用函數時,在函數名后面以空白分隔給定參數列表即可。
		如“testfunc arg1 arg2 ...”
		在函數體中當中,可使用$1, $2, ...調用參數,還可以使用$@, $*, $# 等特殊變量。

函數變量

	變量作用域:
		環境變量:當前shell和子shell有效
		本地變量:只在當前shell進程有效,執行腳本會啟動專用子shell 進程。因此,本地變量的作用范圍是當前shell 腳本程序文件,包括腳本中的函數。
		局部變量:函數結束時變量被自動銷毀
	注意:
		如果函數中有局部變量,如果其名稱同本地變量,使用局部變量。
		在函數中定義局部變量的方法
			local NAME=VALUE 
			declare -I NAME=VALUE 
		定義全局變量
			declare -ig  NAME=VALUE 

函數遞歸

	函數可以直接或間接地調用自身。
	在函數的遞歸調用中,函數既是調用者,又是被調用者。
	遞歸函數的調用過程就是反復地調用其自身,每調用一次就進入新的一層。
	從基礎層開始來計算,注意遞歸的層數。
	遞歸示例:
		階乘
			階乘是數學術語一個正整數的階乘(factorial)是所有小於及等於該數的正整數的積,並且有0 的階乘為1 ,自然數n 的階乘寫作n!
			n!=1 ×2 ×3 ×... ×n
			階乘亦可以遞歸方式定義:
				0!=1 
				n!=n(n-1)(n-2)...1
				n(n-1)! = n(n-1)(n-2)!
		腳本示例:cat fact.sh
			#!/bin/bash
			#
			fact() {
				if [ $1 -eq 0 -o $1 -eq 1 ]; then
						echo 1
				else
					echo $[$1*$(fact $[$1-1])] or echo $[$1*`fact $[$1-1]`]
				fi
			}
			fact $1
		fork炸彈
			fork 炸彈是一種惡意程序,它的內部是一個不斷在fork 進程的無限循環,實質是一個簡單的遞歸程序。
			由於程序是遞歸的,如果沒有任何限制,這會導致這個簡單的程序迅速耗盡系統里面的所有資源
			函數實現
				:(){ :|:& };:
				bomb() { bomb | bomb & }; bomb
			腳本實現
				cat Bomb.sh
				#!/bin/bash
				./$0|./$0&


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM