在本指南中,我們将向 linux 新手展示如何可靠地存儲自定義的 shell 腳本,解釋如何編寫 shell 函數和函數庫,以及如何在其它的腳本中使用函數庫中的函數。
<a target="_blank"></a>
為了在執行你自己的腳本時不必輸入腳本所在位置的完整或絕對路徑,腳本必須被存儲在 <code>$path</code> 環境變量所定義的路徑裡的其中一個。
使用下面的指令可以檢視你系統中的 <code>$path</code> 環境變量:
<code>$ echo $path</code>
<code>/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games</code>
通常來說,如果在使用者的家目錄下存在名為 <code>bin</code> 的目錄,你就可以将 shell 腳本存儲在那個目錄下,因為那個目錄會自動地被包含在使用者的 <code>$path</code> 環境變量中(lctt 譯注:在 centos 6/7 下是這樣的,在 debian 8 下不是這樣的,在 ubuntu 16.04 下又是這樣的)。
是以,在你的主目錄下建立 <code>bin</code> 目錄吧(當然這裡也可以用來存儲 perl、awk 或 python 的腳本,或者其它程式):
<code>$ mkdir ~/bin</code>
接着,建立一個名為 <code>lib</code>(libraries 的簡寫)的目錄來存放你自己的函數庫。你也可以在其中存放其它程式設計語言的函數庫,如 c ,python 等語言。在 <code>lib</code> 目錄下建立另一個名為 <code>sh</code> 的目錄,這個目錄将被用來存放你的 shell 函數庫:
<code>$ mkdir -p ~/lib/sh</code>
一個 <code>shell 函數</code> 就是在腳本中能夠完成特定任務的一組指令。它們的工作原理與其他程式設計語言中的過程(lctt 譯注:可能指的是類似 sql 中的存儲過程之類的吧)、子例程、函數類似。
編寫一個函數的文法如下:
<code>函數名() { 一系列的指令 }</code>
( lctt 校注:在函數名前可以加上 <code>function</code> 關鍵字,但也可省略不寫)
例如,你可以像下面那樣在一個腳本中寫一個用來顯示日期的函數:
<code>showdate() {date;}</code>
每當你需要顯示日期時,隻需調用該函數的函數名即可:
<code>$ showdate</code>
簡單來說 shell 函數庫也是一個 shell 腳本,不過你可以在一個函數庫中僅存儲其它 shell 腳本中需要調用的函數。
下面展示的是在我的 <code>~/lib/sh</code> 目錄下一個名為 <code>libmyfuncs.sh</code> 的庫函數:
<code>#!/bin/bash</code>
<code>### function to clearly list directories in path</code>
<code>showpath() {</code>
<code>oldifs="$ifs" ### store old internal field separator</code>
<code>ifs=: ### specify a new internal field separator</code>
<code>for dir in $path<br> do<br> echo $dir<br> done</code>
<code>ifs="$oldifs" ### restore old internal field separator</code>
<code>}</code>
<code>### function to show logged user</code>
<code>showusers() {</code>
<code>echo -e “below are the user logged on the system:\n”</code>
<code>w</code>
<code>### print a user’s details</code>
<code>printuserdets() {</code>
<code>oldifs="$ifs" ### store old internal field separator</code>
<code>ifs=: ### specify a new internal field separator</code>
<code>read -p "enter user name to be searched:" uname ### read username</code>
<code>echo ""</code>
<code>### read and store from a here string values into variables</code>
<code>### using : as a field delimiter</code>
<code>read -r username pass uid gid comments homedir shell <<< "$(cat /etc/passwd | grep "^$uname")"</code>
<code>### print out captured values</code>
<code>echo -e "username is : $username\n"</code>
<code>echo -e "user's id : $uid\n"</code>
<code>echo -e "user's gid : $gid\n"</code>
<code>echo -e "user's comments : $comments\n"</code>
<code>echo -e "user's home dir : $homedir\n"</code>
<code>echo -e "user's shell : $shell\n"</code>
<code>ifs="$oldifs" ### store old internal field separator</code>
儲存檔案并且給腳本添加執行權限。
要使用某個 <code>lib</code> 目錄下的函數,首先你需要按照下面的形式 将包含該函數的函數庫導入到需要執行的 shell 腳本中:
<code>$ . /path/to/lib</code>
<code>或</code>
<code>$ source /path/to/lib</code>
(lctt 譯注:第一行的 <code>.</code> 和路徑間必須是有空格的)
這樣你就可以像下面示範的那樣,在其它的腳本中使用來自 <code>~/lib/sh/libmyfuncs.sh</code> 的 <code>printuserdets</code> 函數了。
在下面的腳本中,如果要列印出某個特定使用者的詳細資訊,你不必再一一編寫代碼,而隻需要簡單地調用已存在的函數即可。
建立一個名為 <code>test.sh</code> 的新檔案:
<code>### include lib</code>
<code>. ~/lib/sh/libmyfuncs.sh</code>
<code>### use function from lib</code>
<code>printuserdets</code>
<code>### exit script</code>
<code>exit 0</code>
儲存這個檔案,并使得這個腳本可被執行,然後運作它:
<code>$ chmod 755 test.sh</code>
<code>$ ./test.sh</code>

編寫 shell 函數
在本文中,我們介紹了在哪裡可靠地存儲 shell 腳本,如何編寫自己的 shell 函數和函數庫,以及如何在一個普通的 shell 腳本中從函數庫中調用庫中的某些函數。
原文釋出時間為:2017-03-15
本文來自雲栖社群合作夥伴“linux中國”