Linux Bash Shell學習(七):shell程式設計基礎——執行Shell指令碼、function
本文也即《Learning the bash Shell》3rd Edition的第四章Basic Shell Programming之讀書筆記,但我們將不限於此。
執行shell指令碼程式
一個包含shell命令的指令碼就是一個shell程式,例如.bash_profile。我們建立shell指令碼,允許的時候可以通過兩種方式:一、source ;二、只敲入檔名,按回車就可以執行,這種方式更為便捷。我們需要將檔案放置在命令搜尋路徑下(在Linux Bash學習(六):設定環境引數 中介紹),否則需要指出絕對路徑,例如在當前目錄,使用./, 另外我們還需要將檔案的許可權設定為可執行檔案,採用$ chmod +x 的方式設定,+x表示增加執行的許可權。
這兩種方式是由區別的。採用source就如同我們在terminal上敲入命令一樣。採用後一種方式,系統執行一個子程式,它copy了shell,叫作subshell,主shell等待子shell執行結束。另外我們設定讓子shell後臺執行,即 & 。
這個區別還體現在export 的使用上,例如我們設定aa=hello, world,這個變數在命令列中有效,但是在指令碼檔案是無效,需要使用export aa='hello, world ' 來保證在subprocess中也是有效,即可以用於指令碼檔案中。
函式Functions
使用function有兩個原因:一、function存放在系統的記憶體,所以呼叫的使用,效率更高;二、更好地組織長的bash,使之模組化。定義function,有兩個方式:
function functname {
shell commands
}
functname ( ){
shell commands
}
上面兩種方式沒有區別。我們可以通過unset –f functname 來刪除函式的定義。 當我們定義一個function,將它的名字和定義存放在記憶體,我們可以象呼叫shell指令碼的方式來呼叫它。我們通過declare -f 來檢視當前已經定義的function情況,如果我們只檢視function名字,使用declare -F 。我們可以在命令列中敲入一個function來檢驗,如果我們將function定義在一個檔案中,例如在檔案a,可以用source a 來是指生效,如果我們將a設定為可執行檔案,這function的定義只在該指令碼中有效,如果需要使之仍然有效,保留環境,採用$. ./a ,而不只是$./a 。
Function作為一個整體執行,不會分割為子程式,此外Function的優先順序別高於指令碼。如果有重名,優先順序別依次如下:
- Aliases
- 關鍵字,例如function,if,for
- Functions
- Built-ins,例如cd,type
- 在命令搜尋路徑PATH下的指令碼和可執行檔案
如果我們需要檢視所使用命令屬於哪種,用type name ,例如aa是個alias(表示pwd),同樣我們也定義了它作為一個function,根據優先順序別,aa優先作為alias,type aa,我們可以得到aa is aliased to ‘pwd’,可以用type –a(或者-all) name ,來檢視aa代表的所有含義。如果使用非最優先順序別或者重新定義優先順序別的先後順序,在書的第7章,我們先放下此話題不表。上述的命令將顯示詳細內容,可以用type –t name 的方式,檢視型別,將返回alias | keyword | function | builtin | file。type –p name 用於檢視file的路徑,如果型別不是file將沒有返回,而type –P name 則強制查詢file的路徑。例如一個重名,它是一個alias,也是一個在PATH目錄下的可執行檔案。-p則沒有返回,-P這返回檔案的絕對路徑。
位置引數
在指令碼命令中,有時是帶有引數,這些引數可以通過位置變數來獲取。例如我們有個指令碼檔案叫做test,執行的使用帶引數,即$./test param1 param2 param3,我們可以在指令碼中來獲取引數的值。使用$N,其中$0是./test,它表示執行的指令碼名字,剩餘的為所帶引數,$1為param1,$2為param2,如此類推,如果N大於實際引數的數目,為空。我們一般將位置變數是從$1開始。
$* 表示所有引數組成的一個字串,在上面的例子中,為param1 param2 param3。這些引數之間的間隔是IFS的首個字母即空格,IFS包括TAB,空格,換行等字元。
$@ 等同於"$1" "$2"... "$N"。
$# 表示引數的個數,在上面的例子中為3。
這些位置變數都是隻讀,不能賦值的。$*和$@非常相似,一般而言輸出是一樣的。$*的分割是在IFS的字元,我們可以重新定義IFS的字元,將導致不同的輸出結果。我們在指令碼中定義IFS=, ,即可將輸出改用逗號做為分割,這個指令碼名字為a,執行./a h1 h2,則$#=2,表示有兩個引數,$@為h1 h2,$*為h1,h2 ,輸出結果不一樣。
同樣這些位置變數可以用於function中,並對function的引數進行體現,即是local的,屬於function,但是$0是例外,他表示指令碼的名字,這個引數是gobal的。下面是個例子。指令碼a內容如下:
hello ()
{
var="hello";
echo "Hello"
echo "Hello: param num is $#"
echo "Hello: $@"
echo "Hello: $*"
echo "Hello: $0 $1 $2"
echo "Hello: var=$var";
}
var="hello";
echo "main: param num is $#"
echo "main: $@"
echo "main: $*"
echo "main: $0 $1 $2"
echo "main: var=$var";
hello h1 h2
我們執行./a a1 a2 a3
main: param num is 3
main: a1 a2 a3
main: a1 a2 a3
main: ./a a1 a2
main: var=main
Hello
Hello: param num is 2
Hello: h1 h2
Hello: h1 h2
Hello: ./a h1 h2
Hello: var=hello
除了$0外,所有的位置變數都是local的,即如果在function中,則在function中有效。同樣,使用者定義的其他變數,也是local的,即在最近的{}內有效。見上面例子中的使用者變數var。我們可以在function中定義var加上local來特別標明這是一個本地引數,上面的例子在函式hello,可以使用local var=”hello” 。
避免歧義的變數定義
實際上我們使用$varname,是${varname} 的一個縮寫。有時我們不能使用縮寫,例如我們需要獲取第10個引數,使用$10,這實際是第一個引數加上“0”,需要使用${10}。又例如,我們希望顯示程式號,並在後面僅跟_、字母或者數字,我們使用echo $UID_,會見UID_看作一個整體,即echo ${UID_},因此是空,需要使用echo ${UID}_,假設程式號為1000,則為1000_。如果一個變數後面緊跟著_、字母或者數字,安全起見,需要用大括號。
相關連結: 我的Linux操作相關文章
相關文章
- Linux Bash Shell學習(八):shell程式設計基礎——string操作Linux程式設計
- Linux Shell程式設計(3)——執行shell指令碼Linux程式設計指令碼
- Linux_day06_01_Shell指令碼程式設計_Bash基礎Linux指令碼程式設計
- shell指令碼程式設計基礎指令碼程式設計
- 【學習】Linux Shell指令碼程式設計Linux指令碼程式設計
- Linux Shell指令碼程式設計-基礎1Linux指令碼程式設計
- BASH Shell的指令碼程式設計(轉)指令碼程式設計
- shell和bash指令碼命令學習指令碼
- bash shell指令碼執行方法總結指令碼
- 高階bash/shell指令碼程式設計指南指令碼程式設計
- 【Linux學習筆記29】shell指令碼基礎Linux筆記指令碼
- Shell指令碼基礎指令碼
- Linux shell:執行shell指令碼的幾種方式Linux指令碼
- Shell基礎教程七:Shell字串字串
- 執行shell指令碼指令碼
- Linux基礎五(shell指令碼)Linux指令碼
- Bash Shell 基礎特性
- Linux學習(Shell基礎)Linux
- Shell程式設計-基礎程式設計
- shell程式設計基礎程式設計
- Shell程式設計基礎學習之五:重定向與指令碼除錯程式設計指令碼除錯
- Linux shell 指令碼基礎介紹Linux指令碼
- shell簡介入門bash程式設計之執行(轉)程式設計
- Shell 指令碼程式設計陷阱指令碼程式設計
- shell指令碼程式設計學習筆記-運算子指令碼程式設計筆記
- shell指令碼程式設計學習筆記——變數指令碼程式設計筆記變數
- crontab執行shell指令碼指令碼
- 如何學習shell程式設計?Linux運維學習shell程式設計是什麼程式設計Linux運維
- Shell程式設計-01-Shell指令碼初步入門程式設計指令碼
- Linux學習-shell基礎02Linux
- Shell指令碼執行有哪些方式?linux系統學習指令碼Linux
- Linux下如何執行Shell指令碼Linux指令碼
- shell程式設計基礎二程式設計
- 前端學習 linux —— shell 程式設計前端Linux程式設計
- shell程式設計–bash變數程式設計變數
- 9.bash shell程式設計程式設計
- 玩轉Linux – shell 程式設計基礎Linux程式設計
- 什麼是shell指令碼?Linux為什麼學習shell?指令碼Linux