如何改進你的指令碼程式

大雄45發表於2021-11-14
導讀 你是否曾經檢視過某個軟體發行方提供的安裝用的 script程式?為了能夠適應不同使用者的系統配置,順利完成安裝,這些 程式經常包含很多函式和邏輯分支。多年來,我積累了一些改進指令碼程式的一些技巧,這裡分享幾個,希望能對朋友們也有用。這裡列出一組短指令碼示例,展示給大家做指令碼樣本。

如何改進你的指令碼程式如何改進你的指令碼程式

初步嘗試

我嘗試寫一個指令碼程式時,原始程式往往就是一組 行,通常就是呼叫標準 完成諸如更新網頁內容之類的工作,這樣可以節省時間。其中一個類似的工作是解壓檔案到 Apache 網站伺服器的主目錄裡,我的最初指令碼程式大概是下面這樣:

cp january_schedule.tar.gz /usr/apache/home/calendar/ 
cd /usr/apache/home/calendar/ 
tar zvxf january_schedule.tar.gz

這幫我節省了時間,也減少了鍵入多條命令操作。時日久了,我掌握了另外的技巧,可以用 Bash 指令碼程式完成更難的一些工作,比如說建立軟體安裝包、安裝軟體、備份檔案系統等工作。

1、條件分支結構

和眾多其他程式語言一樣,指令碼程式的條件分支結構同樣是強大的常用技能。條件分支結構賦予了計算機程式邏輯能力,我的很多例項都是基於條件邏輯分支。

基本的條件分支結構就是 if 條件分支結構。透過判定是否滿足特定條件,可以控制程式選擇執行相應的指令碼命令段。比如說,想要判斷系統是否安裝了 Java ,可以透過判斷系統有沒有一個 Java 庫目錄;如果找到這個目錄,就把這個目錄路徑新增到可執行程式路徑,也就可以呼叫 Java 庫應用了。

if [ -d "$JAVA_HOME/bin" ] ; then PATH="$JAVA_HOME/bin:$PATH"
2、限定執行許可權

你或許想只允許特定的使用者才能執行某個指令碼程式。除了   的許可權許可管理,比如對使用者和使用者組設定許可權、透過 SELinux 設定此類的保護許可權等,你還可以在指令碼里設定邏輯判斷來設定執行許可權。類似的情況可能是,你需要確保只有網站程式的所有者才能執行相應的網站初始化操作指令碼。甚至你可以限定只有 root 使用者才能執行某個指令碼。這個可以透過在指令碼程式裡設定邏輯判斷實現,Linux 提供的幾個環境變數可以幫忙。其中一個是儲存使用者名稱稱的變數 $USER, 另一個是儲存使用者識別碼的變數 $UID 。在指令碼程式裡,執行使用者的 UID 值就儲存在 $UID 變數裡。

使用者名稱判別

第一個例子裡,我在一個帶有幾個應用伺服器例項的多使用者環境裡指定只有使用者 jboss1 可以執行指令碼程式。條件 if 語句主要是判斷,“要求執行這個指令碼程式的使用者不是 jboss1 嗎?”當此條件為真時,就會呼叫第一個 echo 語句,接著是 exit 1,即退出這個指令碼程式。

if [ "$USER" != 'jboss1' ]; then 
     echo "Sorry, this script must be run as JBOSS1!" 
     exit 1 
fi 
echo "continue script"
根使用者判別

接下來的例子是要求只有根使用者才能執行指令碼程式。根使用者的使用者識別碼(UID)是 0,設定的條件判斷採用大於運算子(-gt),所有 UID 值大於 0 的使用者都被禁止執行該指令碼程式。

if [ "$UID" -gt 0 ]; then 
     echo "Sorry, this script must be run as ROOT!" 
     exit 1 
fi 
echo "continue script"
3、帶引數執行程式

可執行程式可以附帶引數作為執行選項,命令列指令碼程式也是一樣,下面給出幾個例子。在這之前,我想告訴你,能寫出好的程式並不只是寫出我們想要它執行什麼的程式,程式還需要不執行我們不要它執行的操作。如果執行程式時沒有提供引數造成程式缺少足夠資訊,我願意指令碼程式不要做任何破壞性的操作。因而,程式的第一步就是確認命令列是否提供了引數,判定的條件就是引數數量 $# 是否為 0 ,如果是(意味著沒有提供引數),就直接終止指令碼程式並退出操作。

if [ $# -eq 0 ]; then 
    echo "No arguments provided" 
    exit 1 
fi 
echo "arguments found: $#"
多個執行引數

可以傳遞給指令碼程式的引數不止一個。指令碼使用內部變數指代這些引數,內部變數名用非負整數遞增標識,也就是 $1、$2、$3 等等遞增。我只是擴充套件前面的程式,並在下面一行輸出顯示使用者提供的前三個引數。顯然,要針對所有的每個引數有對應的響應需要更多的邏輯判斷,這裡的例子只是簡單展示引數的使用。

echo $1 $2 $3

我們在討論這些引數變數名,你或許有個疑問,“引數變數名怎麼跳過了 $0,(而直接從$1 開始)?”

是的,是這樣,這是有原因的。變數名 $0 確實存在,也非常有用,它儲存的是被執行的指令碼程式的名稱。

echo $0

程式執行過程中有一個變數名指代程式名稱,很重要的一個原因是,可以在生成的日誌檔名稱裡包含程式名稱,最簡單的方式應該是呼叫一個 echo 語句。

echo test >> $0.log

當然,你或許要增加一些程式碼,確保這個日誌檔案存放在你希望的路徑,日誌名稱包含你認為有用的資訊。

4、互動輸入

指令碼程式的另一個好用的特性是可以在執行過程中接受輸入,最簡單的情況是讓使用者可以輸入一些資訊。

echo "enter a word please:" 
read word 
echo $word

這樣也可以讓使用者在程式執行中作出選擇。

read -p "Install Software ?? [Y/n]: " answ 
if [ "$answ" == 'n' ]; then 
    exit 1 
fi 
    echo "Installation starting..."
5、出錯退出執行

幾年前,我寫了個指令碼,想在自己的電腦上安裝最新版本的 Java 開發工具包(JDK)。這個指令碼把 JDK 檔案解壓到指定目錄,建立更新一些符號連結,再做一下設定告訴系統使用這個最新的版本。如果解壓過程出現錯誤,在執行後面的操作就會使整個系統上的 Java 破壞不能使用。因而,這種情況下需要終止程式。如果解壓過程沒有成功,就不應該再繼續進行之後的更新操作。下面語句段可以完成這個功能。

tar kxzmf jdk-8u221-linux-x64.tar.gz -C /jdk --checkpoint=.500; ec=$? 
if [ $ec -ne 0 ]; then 
     echo "Installation failed - exiting." 
     exit 1 
fi

下面的單行語句可以給你快速展示一下變數 $? 的用法。

ls T; ec=$?; echo $ec

先用 touch T 命令建立一個檔名為 T 的檔案,然後執行這個單行命令,變數 ec 的值會是 0。然後,用 rm T 命令刪除檔案,再執行該單行命令,變數 ec 的值會是 2,因為檔案 T 不存在,命令 ls 找不到指定檔案報錯。

在邏輯條件裡利用這個出錯標識,參照前文我使用的條件判斷,可以使指令碼檔案按需完成設定操作。

結語

要完成複雜的功能,或許我們覺得應該使用諸如 Python、C 或 Java 這類的高階程式語言,然而並不盡然,指令碼程式語言也很強大,可以完成類似任務。要充分發揮指令碼的作用,有很多需要學習的,希望這裡的幾個例子能讓你意識到指令碼程式設計的強大。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2791850/,如需轉載,請註明出處,否則將追究法律責任。

相關文章