在 Linux 系統下,Shell 指令碼可以在各種不同的情形下幫到我們,例如展示資訊,甚至 自動執行特定的系統管理任務,建立簡單的命令列工具等等。
在本指南中,我們將向 Linux 新手展示如何可靠地儲存自定義的 shell 指令碼,解釋如何編寫 shell 函式和函式庫,以及如何在其它的指令碼中使用函式庫中的函式。
Shell 指令碼要儲存在何處
為了在執行你自己的指令碼時不必輸入指令碼所在位置的完整或絕對路徑,指令碼必須被儲存在 $PATH 環境變數所定義的路徑裡的其中一個。
使用下面的命令可以檢視你係統中的 $PATH 環境變數:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
通常來說,如果在使用者的家目錄下存在名為 bin 的目錄,你就可以將 shell 指令碼儲存在那個目錄下,因為那個目錄會自動地被包含在使用者的 $PATH 環境變數中(LCTT 譯註:在 Centos 6/7 下是這樣的,在 Debian 8 下不是這樣的,在 Ubuntu 16.04 下又是這樣的) 。
因此,在你的主目錄下建立 bin 目錄吧(當然這裡也可以用來儲存 Perl 、 Awk 或 Python 的指令碼,或者其它程式):
$ mkdir ~/bin
接著,建立一個名為 lib(libraries 的簡寫)的目錄來存放你自己的函式庫。你也可以在其中存放其它程式語言的函式庫,如 C ,Python 等語言。在 lib 目錄下建立另一個名為 sh 的目錄,這個目錄將被用來存放你的 shell 函式庫:
$ mkdir -p ~/lib/sh
建立你自己的 Shell 函式和函式庫
一個 shell 函式 就是在指令碼中能夠完成特定任務的一組命令。它們的工作原理與其他程式語言中的過程(LCTT 譯註:可能指的是類似 SQL 中的儲存過程之類的吧)、子例程、函式類似。
編寫一個函式的語法如下:
函式名 () { 一系列的命令 }
( LCTT 校注:在函式名前可以加上 function 關鍵字,但也可省略不寫)
例如,你可以像下面那樣在一個指令碼中寫一個用來顯示日期的函式:
showDATE() {date;}
每當你需要顯示日期時,只需呼叫該函式的函式名即可:
$ showDATE
簡單來說 shell 函式庫也是一個 shell 指令碼,不過你可以在一個函式庫中僅儲存其它 shell 指令碼中需要呼叫的函式。
下面展示的是在我的 ~/lib/sh 目錄下一個名為 libMYFUNCS.sh 的庫函式:
#!/bin/bash
### Function to clearly list directories in PATH
showPATH() {
oldifs=”$IFS” ### store old internal field separator
IFS=: ### specify a new internal field separator
for DIR in $PATH
do
echo $DIR
done
IFS=”$oldifs” ### restore old internal field separator
}
### Function to show logged user
showUSERS() {
echo -e “Below are the user logged on the system:n”
w
}
### Print a user’s details
printUSERDETS() {
oldifs=”$IFS” ### store old internal field separator
IFS=: ### specify a new internal field separator
read -p “Enter user name to be searched:” uname ### read username
echo “”
### read and store from a here string values into variables
### using : as a field delimiter
read -r username pass uid gid comments homedir shell <<< "$(cat /etc/passwd | grep "^$uname")"
### print out captured values
echo -e "Username is : $usernamen"
echo -e "User's ID : $uidn"
echo -e "User's GID : $gidn"
echo -e "User's Comments : $commentsn"
echo -e "User's Home Dir : $homedirn"
echo -e "User's Shell : $shelln"
IFS="$oldifs" ### store old internal field separator
}
儲存檔案並且給指令碼新增執行許可權。
如何從函式庫中呼叫函式
要使用某個 lib 目錄下的函式,首先你需要按照下面的形式 將包含該函式的函式庫匯入到需要執行的 shell 指令碼中:
$ . /path/to/lib
或
$ source /path/to/lib
(LCTT 譯註:第一行的 . 和路徑間必須是有空格的)
這樣你就可以像下面演示的那樣,在其它的指令碼中使用來自 ~/lib/sh/libMYFUNCS.sh 的 printUSERDETS 函式了。
在下面的指令碼中,如果要列印出某個特定使用者的詳細資訊,你不必再一一編寫程式碼,而只需要簡單地呼叫已存在的函式即可。
建立一個名為 test.sh 的新檔案:
#!/bin/bash
### include lib
. ~/lib/sh/libMYFUNCS.sh
### use function from lib
printUSERDETS
### exit script
exit 0
儲存這個檔案,並使得這個指令碼可被執行,然後執行它:
$ chmod 755 test.sh
$ ./test.sh