時間:2017年10月09日星期一
說明:本文部份內容均摘取自書籍《Linux命令行與shell腳本編程大全》,版權歸原做者全部。《Linux命令行與shell腳本編程大全》(第三版)第十七章學習總結shell
本章內容編程
基本的腳本函數 返回值 在函數中使用變量 屬組變量和函數 函數遞歸 建立庫 在命令行上使用函數
格式一數組
function name{ commands }
格式二bash
name(){ commands }
說明函數
name屬性定義了賦予函數的惟一名稱 commands是構成函數的一條或多條bash shell命令
編寫test1.sh腳本oop
#!/bin/bash function func1 { echo "This is an example of a function" } count=1 while [ $count -le 5 ] do func1 count=$[ $count + 1 ] done echo "This is the end of the loop" func1 echo "Now this is the end of the script"
函數需先定義,再使用學習
編寫test2.sh腳本動畫
#!/bin/bash count=1 echo "This line comes before the function definition" function func1 { echo "This is an example of a function" } while [ $count -le 5 ] do func1 count=$[ $count + 1 ] done echo "This is the end of the loop" func2 echo "Now this is the end of the script" function func2 { echo "This is an example of a function" }
函數名必須惟一,不然新定義的函數會覆蓋原來函數this
編寫test3.sh腳本命令行
#!/bin/bash function func1 { echo "This is the first definition of the function name" } func1 function func1 { echo "This is a repeat of the same function name" } func1 echo "This is the end of the script"
bash shell會把函數當作一個小型腳本,運行結束時會返回一個退出狀態碼
默認狀況下,函數的退出狀態碼時函數中最後一條命令返回的退出狀態碼 在函數執行後,能夠用標準變量$?來肯定函數的退出狀態碼 只能判斷函數中最後一條命令是否運行成功,沒法判斷函數中其它命令 使用函數的默認退出狀態碼時很危險的
編寫test4.sh腳本
#!/bin/bash func1() { echo "trying to display a non-existent file" ls -l badfile } echo "testing the function:" func1 echo "The exit status is: $?"
使用return命令來退出函數並返回指定一個整數值的退出狀態碼 函數一結束就去返回值 退出狀態碼必須時0~255
編寫test5.sh腳本
#!/bin/bash function db1 { read -p "Enter a value: " value echo "doubling the value" return $[ $value * 2 ] } db1 echo "The new value is $?"
能夠將函數的輸出保存到變量中
編寫test5b.sh腳本
#!/bin/bash function db1 { read -p "Enter a value: " value echo $[ $value *2 ] } result=$(db1) echo "The new value is $result"
函數能夠使用標準的參數環境變量來表示命令行上傳給函數的參數。 例如,函數名會在$0變量中定義,函數命令行上的任何參數都會經過$一、$2等定義。 也能夠用特殊變量$#來判斷傳給函數的參數數目。
在腳本中指定函數時,必須將參數和函數放在同一行
編寫test6.sh腳本
#!/bin/bash function addem { if [ $# -eq 0 ] || [ $# -gt 2 ] then echo -1 elif [ $# -eq 1 ] then echo $[ $1 + $1 ] else echo $[ $1 + $2 ] fi } echo -n "Adding 10 and 15:" value=$(addem 10 15) echo $value echo -n "Let's try adding just one number:" value=$(addem 10) echo $value echo -n "Now trying adding no numbers:" value=$(addem) echo $value echo -n "Finally, try adding three numbers:" value=$(addem 10 15 200) echo $value
將傳遞給腳本的變量傳給函數
編寫test7.sh腳本
#!/bin/bash function func7 { echo $[ $1 * $2 ] } if [ $# -eq 2 ] then value=$(func7 $1 $2) echo "The result is $value" else echo "Usage: test7 a b" fi
1.全局變量
全局變量是在shell腳本中任何地方都有效的變量。 若是你在腳本的主體部分定義了一個全局變量,那麼能夠在函數內讀取它的值。 若是你在函數內定義了一個全局變量,能夠在腳本的主題部分讀取它的值。 默認狀況下,在腳本中定義的任何變量都是全局變量,在函數外定義的變量能夠在函數內訪問。
編寫test8.sh腳本
#!/bin/bash function db1 { value=$[ $value * 2 ] } read -p "Enter a value: " value db1 echo "The new value is: $value"
2.局部變量
無需在函數中使用全局變量,函數內部使用的任何變量均可以被聲明成局部變量。 在變量聲明的前面加上local關鍵字便可。 也能夠在變量賦值語句中使用local關鍵字。
編寫test9.sh腳本
#!/bin/bash function func1 { local temp=$[ $value + 5 ] result=$[ $temp * 2 ] } temp=4 value=6 func1 echo "The result is $result" if [ $temp -gt $value ] then echo "temp is larger" else echo "temp is smaller" fi
將數組的值分解成單個的值做爲函數參數使用
編寫test10.sh腳本
#!/bin/bash function testit { local newarray newarray=($@) echo "The new array value is: ${newarray[*]}" } myarray=(1 2 3 4 5) echo "The original array is ${myarray[*]}" testit ${myarray[*]}
編寫test11.sh腳本
#!/bin/bash function addarray { local sum=0 local newarray newarray=($(echo "$@")) for value in ${newarray[*]} do sum=$[ $sum + $value ] done echo $sum } myarray=(1 2 3 4 5) echo "The original array is: ${myarray[*]}" arg1=$(echo ${myarray[*]}) result=$(addarray $arg1) echo "The result is $result"
從函數裏向shell腳本傳回數組變量
編寫test12.sh腳本
#!/bin/bash function arraydb1r { local origarray local newarray local elements local i origarray=($(echo "$@")) newarray=($(echo "$@")) elements=$[ $# -1 ] for (( i = 0; i<= $elements; i++ )) { newarray[$i]=$[ ${origarray[$i]} * 2 ] } echo ${newarray[*]} } myarray=(1 2 3 4 5) echo "The original array is: ${myarray[*]}" arg1=$(echo ${myarray[*]}) result=($(arraydb1r $arg1)) echo "The new array is: ${result[*]}"
使用遞歸計算階乘
編寫test13.sh腳本
#!/bin/bash function factorial { if [ $1 -eq 1 ] then echo 1 else local temp=$[ $1 -1 ] local result=$(factorial $temp) echo $[ $result * $1 ] fi } read -p "Enter value: " value result=$(factorial $value) echo "The factorial of $value is: $result"
若是多個腳本須要使用同一段代碼,能夠使用函數庫文件,而後在多個腳本中引用該庫文件
1.建立一個庫文件
編寫myfuncs文件
function addem { echo $[ $1 + $2 ] } function multem { echo $[ $1 * $2 ] } function divem { if [ $2 -ne 0 ] then echo $[ $1 / $2 ] else echo -1 fi }
2.使用這個庫文件
編寫test14.sh腳本
#!/bin/bash . ./myfuncs value1=10 value2=5 result1=$(addem $value1 $value2) result2=$(multem $value1 $value2) result3=$(divem $value1 $value2) echo "The result of adding them is: $result1" echo "The result of multiplying them is: $result2" echo "The result of dividing them is: $result3"
由於shell會解釋用戶輸入的命令,全部能夠在命令行上直接定義一個函數
執行一下命令
function divem { echo $[ $1 / $2 ]; } divem 100 5
警告:在命令行上建立函數時要特別當心。若是給函數起了個跟內建命令或另外一個命令相同的名字,函數將會覆蓋原來的命令。
1.直接定義函數
能夠直接在主目錄下的.bashrc文件中定義函數
如在文件末尾加上
function addem { echo $[ $1 + $2 ] }
2.讀取函數文件
能夠使用source命令(即點操做符)將庫文件中的函數添加到.bashrc腳本中
如在文件末尾加上
. /home/zc/libraries/myfuncs
函數的應用毫不僅限於建立本身的函數自娛自樂。在開源世界中,共享代碼纔是關鍵,而這一點一樣適用於腳本函數。這裏將說明如何下載、安裝、使用GNU shtool shell腳本函數庫。
下載地址:ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz
解壓文件:tar -zxvf shtool-2.0.8.tar.gz
shtool文件必須針對特定的Linux環境進行配置
配置工做必須使用標準的configure和make命令,這兩個命令一般用於C編程環境
執行命令
./configure make sudo make install
shtool庫提供了大量方便的、可用於shell腳本的函數
shtool庫函數
函數:描述 Arx:建立歸檔文件(包含一些擴展功能) Echo:顯示字符串,並提供了一些擴展構件 fixperm:改變目錄樹中的文件權限 install:安裝腳本或文件 mdate:顯示文件或目錄的修改時間 mkdir:建立一個或更多目錄 Mkln:使用相對路徑建立連接 mkshadow:建立一顆陰影樹 move:帶有替換功能的文件移動 Path:處理程序路徑 platform:顯示平臺標識 Prop:顯示一個帶有動畫效果的進度條 rotate:轉置日誌文件 Scpp:共享的C預處理器 Slo:根據庫的類別,分離連接器選項 Subst:使用sed的替換操做 Table:以表格的形式顯示由字段分割(field-separated)的數據 tarball:從文件和目錄中建立tar文件 version:建立版本信息文件
shtool函數的使用格式
shtool [options] [function [options] [args]]
能夠在命令行或本身的shell腳本中直接使用shtool函數
編寫test16.sh腳本
#!/bin/bash shtool platform
shell腳本函數容許將腳本中多處用到的代碼放到一個地方。能夠建立一個包含該代碼塊的函數,而後在腳本中經過函數名來引用這塊代碼,而不用一次次重複寫那段代碼。