第三部分高級shell腳本編程
第17章創建函數
17.1 腳本函數基礎
17.1.1 創建函數
在bash shell 腳本中創建函數的語法有兩種。第一種語法是使用關鍵字function,隨后跟
上分配給該代碼塊的函數名:
function name {
commands
}
17.1.2 使用函數
要在腳本中使用函數,只需像其他shell 命令一樣寫出函數名即可
17.2 函數返回值
17.2.1 默認的退出狀態碼
在默認情況下,函數的退出狀態碼是函數中最后一個命令返回的退出狀態碼。函數執行結束
后,可以使用標準變量$?來確定函數的退出狀態碼。該函數的退出狀態碼是1,因為函數中的最后一個命令執行失敗了。但你無法知道該函數中的其他命令是否執行成功。
17.2.2 使用return命令
使用return 命令以特定的退出狀態碼退出函數。return 命令允許指定一個整數值作為函數的退出狀態碼。當用這種方法從函數中返回值時,一定要小心。為了避免出問題,牢記以下兩個技巧:?函數執行一結束就立刻讀取返回值;退出狀態碼必須介于0~255
$ cat test5
#!/bin/bash
# using the return command in a function
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?" #用$?變量顯示出該結果
$
17.2.3 使用函數輸出
將dbl函數的輸出保存到shell 變量中:result=$(dbl)
$ cat test5b
#!/bin/bash
# using the echo to return a value
function dbl {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(dbl)
echo "The new value is $result"
$
17.3 在函數中使用變量
17.3.1 向函數傳遞參數
函數可以使用標準的位置變量來表示在命令行中傳給函數的任何參數。例如,函數名保存在
$0 變量中,函數參數依次保存在$1、$2 等變量中。也可以用特殊變量$#來確定傳給函數的參數
數量。
在腳本中調用函數時,必須將參數和函數名放在同一行
17.3.2 在函數中處理變量
1. 全局變量
全局變量是在shell 腳本內任何地方都有效的變量。
在默認情況下,在腳本中定義的任何變量都是全局變量。在函數外定義的變量可在函數內正
常訪問
2. 局部變量
無須在函數中使用全局變量,任何在函數內部使用的變量都可以被聲明為局部變量。為此,
只需在變量聲明之前加上local 關鍵字即可
$ cat test9
#!/bin/bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
17.4 數組變量和函數
將數組變量作為函數參數進行傳遞,則函數只會提取數組變量的第一個元素,,必須先將數組變量拆解成多個數組元素,然后將這些數組元素作為函數參數傳遞。最后在函數內部,將所有的參數重新組合成一個新的數組變量。
17.4.1 向函數傳遞數組
$ cat test10
#!/bin/bash
# array variable to function test
function testit {
local newarray # 創建數組
newarray=(`echo "$@"`) #所有的參數重新組合成一個新的數組變量
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
$
$ ./test10
The original array is 1 2 3 4 5
The new array value is: 1 2 3 4 5
$
17.4.2 從函數返回數組
函數先用echo 語句按正確順序輸出數組的各個元素,然后腳本再將數組元素重組成一個新的數組變量
$ cat test12
#!/bin/bash
# returning an array value
function arraydblr {
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[*]}) # echo 語句重組成一個新的數組變量
result=($(arraydblr $arg1)) # 通過$arg1 變量將數組元素作為參數傳給arraydblr 函數。
echo "The new array is: ${result[*]}"
$
$ ./test12
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10
17.5 函數遞歸
局部函數變量的一個特性是自成體系(self-containment)。除了獲取函數參數,自成體系的
函數不需要使用任何外部資源。這個特性使得函數可以遞歸地調用,也就是說函數可以調用自己來得到結果。
17.6 創建庫
bash shell 允許創建函數庫文件,然后在多個腳本中引用此庫文件。
在多個腳本中使用同一段代碼
第一步是創建一個包含腳本中所需函數的公用庫文件,例如:庫文件myfuncs
第二步是在需要用到這些函數的腳本文件中包含myfuncs 庫文件,用source 命令在腳本中運行庫文
$ cat test14
#!/bin/bash
# using functions defined in a library file
. ./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"
$
$ ./test14
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2
$
source 命令有個別名,稱作點號操作符。
17.7 在命令行中使用函數
17.7.1 在命令行中創建函數
1.?采用單行方式來定義函數
$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
?2.采用多行方式來定義函數
使用這種方法,無須在每條命令的末尾放置分號,只需按下回車鍵即可
$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10
17.7.2 在.bashrc文件中定義函數
1. 直接定義函數
可以直接在用戶主目錄的.bashrc 文件中定義函數,只需將函數放在文件末尾即可
2. 源引函數文件
只要是在shell 腳本中,就可以用source 命令(或者其別名,即點號操作符)將庫文件中
的函數添加到.bashrc 腳本中
$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
fi
. /home/rich/libraries/myfuncs # 將庫文件中的函數添加到.bashrc 腳本
$
第18章 圖形化桌面環境中的腳本編程 #
第19章 初識sed和gawk
19.1文本處理
19.1.1 sed編輯器
sed 編輯器被稱作流編輯器(stream editor)
sed 命令的格式如下:?
sed options script file
1. 在命令行中定義編輯器命令
在默認情況下,sed 編輯器會將指定的命令應用于STDIN 輸入流中。因此,可以直接將數據
通過管道傳入sed 編輯器進行處理。
$ echo "This is a test" | sed 's/test/big test/'
This is a big test
$#接將數據通過管道傳入sed 編輯器進行處理, 替換(s)命令,將big test 替換了test
2. 在命令行中使用多個編輯器命令
如果要在sed 命令行中執行多個命令,可以使用-e 選項
$ sed -e 's/brown/red/; s/dog/cat/' data1.txt
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
The quick red fox jumps over the lazy cat.
$
3. 從文件中讀取編輯器命令
?
有大量要執行的sed 命令,那么將其放進單獨的文件通常會更方便一些。可以在sed
命令中用-f 選項來指定文件:
$ cat script1.sed
s/brown/green/
s/fox/toad/
s/dog/cat/
$
$ sed -f script1.sed data1.txt
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
$
19.1.2 gawk編輯器
雖然sed 編輯器非常方便,可以即時修改文本文件
19.2 sed編輯器基礎命令 #
19.2.1 更多的替換選項 #
19.2.2 使用地址 #
19.2.3 刪除行 #
19.2.4 插入和附加文本? #
19.2.5 修改行 #
19.2.6 轉換命令 #
19.2.7 再探打印 #
19.2.8 使用sed處理文件 #
第20章 正則表達式
正則表達式是一種可供Linux 工具過濾文本的自定義模板
第21章 sed進階 #
第22章 gawk進階 #?
第23章 使用其他shell
- dash shell
- zsh shell
?第四部分 創建和管理實用的腳本
第24章 編寫簡單的腳本實用工具
第25章 井井有條
第24章 編寫簡單的腳本實用工具
24.1 備份
定時進行備份(也稱作歸檔)
24.1.1 日常備份 #
24.1.2 創建按小時歸檔的腳本 #
24.2 刪除賬戶
管理本地用戶賬戶絕不僅僅是添加、修改和刪除,還需考慮安全問題、保留工作的需求,以
及精確刪除賬戶。
刪除本地賬戶屬于更復雜的賬戶管理任務,至少需要4 個步驟。
(1) 獲取正確的待刪除用戶賬戶名。
(2)“殺死”系統中正在運行的屬于該賬戶的進程。
(3) 確認系統中屬于該賬戶的所有文件。
(4) 刪除該用戶賬戶。
24.3 系統監控
24.3.1 獲得默認的shell審計功能
使用cut 命令獲取/etc/passwd 文件中所有賬戶的默認shell。
$ cut -d: -f7 /etc/passwd
24.3.2 權限審計功能
SUID(set user ID)和SGID(set group ID)是兩種很方便的權限設置
找出具有這兩種權限的文件和目錄,需要使用find 命令
$ sudo find / -perm /6000 2>/dev/null
第25章 井井有條
25.1 理解版本控制
25.1.1 工作目錄
工作目錄是所有腳本的創建、修改和審查之地。它通常是腳本編寫者的主目錄中的某個子目錄,類似于/home/christine/scripts。最好為每個項目都創建一個新的子目錄,因為Git 會在其中放
置文件,以便進行跟蹤。
25.1.2 暫存區
暫存區也稱為索引。該區域和工作目錄位于同一系統。bash 腳本通過Git 命令(git add)
在暫存區內注冊。通過git init 命令,暫存區在工作目錄中設置了一個名為.git 的隱藏子目錄。
25.1.3 本地倉庫
本地倉庫包括每個腳本文件的歷史記錄。它也會用到工作目錄的.git 子目錄。腳本文件的各
個版本(稱為項目樹)和提交信息之間的關系通過Git 命令(git commit),以對象的方式存儲
在.git/objects/目錄中。
項目樹和提交數據合起來稱為快照。每次提交數據都會創建一個新快照。不過,舊快照并不
會被刪除,依然可以查看。如果需要,還可以返回到之前的快照,這是Git 另一個不錯的特性。
25.1.4 遠程倉庫
在Git 配置中,遠程倉庫通常位于云端,提供代碼托管服務。著名的遠程倉庫有GitHub、GitLab、BitBucket 和Launchpad。不過到目前為止,GitHub 最受歡迎
25.1.5 分支
Git 還提供了一個名為分支的特性,該特性可以在各種腳本項目中發揮作用。分支是本地倉
庫中屬于特定項目的一個區域。
25.1.6 克隆
Git 的另一個特性是復制項目。這個過程稱為克隆。
注意 在Git 中,克隆(cloning)和 分叉(forking)是兩種緊密相關的操作。使用git clone
命令將文件從遠程倉庫下載到本地系統,這一過程是克隆。將文件從一個遠程倉庫復制
到另一個遠程倉庫,這一過程是分叉。
25.1.7 使用Git作為VCS
好處
性能:Git只操作本地文件, 這提高了其部署速度。同遠程倉庫之間收發文件屬于例外
情況。
歷史文件:從文件被注冊那一刻起, Git就開始使用索引來記錄文件的內容。當對本地存
儲庫的提交完成時, Git會及時創建并存儲對該快照的引用。
準確性:Git使用校驗和來保護文件完整性。
去中心化:腳本編寫者可以在同一個項目中工作,但不必位于同一網絡或系統。
25.2 設置Git環境
安裝好git 軟件包之后,為新的腳本項目設置Git 環境涉及以下4 個基本步驟。
(1) 創建工作目錄:?
$ mkdir MWGuard$ cd MWGuard/
(2) 初始化.git/子目錄
$ git init
$ git remote add origin https://github.com/C-Bresnahan/MWGuard.git
$
$ git remote -v
origin https://github.com/C-Bresnahan/MWGuard.git (fetch)
origin https://github.com/C-Bresnahan/MWGuard.git (push)
$
(3) 設置本地倉庫選項
#,則需將姓名和email 地址添加到Git 的全局倉庫配置文件中
$ git config --global user.name "Christine Bresnahan"
$ git config --global user.email "cbresn1723@gmail.com"
(4) 確定遠程倉庫位置
建立好項目的遠程倉庫之后,需要把倉庫地址記下來。隨后向遠程倉庫發送項目文件時,要
用到這個地址。
可以使用git remote add origin URL 命令來添加地址,其中URL 就是遠程倉庫地址:
$ git remote add origin https://github.com/C-Bresnahan/MWGuard.git
$
$ git remote -v
origin https://github.com/C-Bresnahan/MWGuard.git (fetch)
origin https://github.com/C-Bresnahan/MWGuard.git (push)
$