Shell指令碼程式設計規範與變數(shell指令碼必須要知道的規矩!)

Mhh2333發表於2020-12-28

Shell指令碼程式設計規範與變數


Shell是一個特殊的應用程式,它介於作業系統核心與使用者之間,充當了一個"命令直譯器"的角色,負責接收使用者輸入的操作指令(命令)並進行解釋,將需要執行的操作傳遞給核心執行,並輸出執行結果。Bash (/bin/bash)是目前大多數 Linux 版本採用的預設 Shell。

一、Shell指令碼概述

1.Shell指令碼的概念

1)將要執行的命令吧順序儲存到一個文字文件
2)給該檔案可執行許可權,便可執行
3)可結合各種Shell控制語句以完成更復雜的操作

2.Shell指令碼的應用場景

1)重複性操作
2)批量事物處理
3)自動化運維
4)服務執行狀態監控
5)定時任務執行

3.Shell的作用

1)Shell是命令解釋管,使用者與核心之間的“翻譯官”,負責解釋使用者輸入的命令列。

在這裡插入圖片描述

2)使用者登入Shell

  • 登入後預設使用的ShellI程式,一般為/bin/bash
  • 不同Shell的內部指令、執行環境等會有所區別
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
....

在這裡插入圖片描述

二、編寫一個Shell指令碼

1.編寫指令碼程式碼

●使用vim文字編輯器
每行一條Linux命令,按執行順序依次編寫

[root@localhost ~]#vim first.sh #編輯指令碼檔案,以.sh結尾是方便識別出這是個shell指令碼檔案
cd /boot/ #切換到根目錄
pwd  #檢視當前所在目錄
ls -lh vml* #以長格式更人性化的方式顯示以vml開頭的檔案

在這裡插入圖片描述

上述first.sh指令碼檔案中,包括三條命令:cd /boot/、pwd、ls -lh vml*。執行此指令碼檔案後,輸出結果實際上就是這三條命令依次執行的結果,從而實現了“批量處理”。

2.賦予可執行許可權

●使指令碼具有可執行屬性

[root@localhost~]#chmod +x first.sh

在這裡插入圖片描述

3.執行指令碼檔案

1)方法一∶ 指定路徑的命令,要求檔案必須有 x 許可權。(絕對路徑和相對路徑)

chmod +x /root/first.sh

指定絕對路徑∶ /root/first.sh

在這裡插入圖片描述

指定相對路徑∶ ./first.sh

在這裡插入圖片描述

2)方法二∶指定Shell來解釋指令碼,不要求檔案必須有 x 許可權。

sh 指令碼路徑∶ sh first.sh或者sh /root/first.sh

相對路徑(需要在指令碼所在目錄下),此指令碼本來就建立在家目錄(~目錄)下,root的家目錄就是root。

在這裡插入圖片描述

絕對路徑(直接指定檔案具體路徑)

在這裡插入圖片描述

3)方法三:source 指令碼路徑或 . 指令碼路徑(不需要x許可權)

.first.sh 或者 source first.sh(同上對路徑有要求)

在這裡插入圖片描述

這種執行方法會自動切換到boot目錄。這是因為source 以及 . 直接在當前的程式中讀取指令碼的配置,不會開一個新的程式!
source會將指令碼的內容直接容影響到父程式的(因為它不開闢新執行緒,可以說是直接在當前程式中加入指令碼的執行內容)。所以你source之後,裡面配置的變數都會加入到當前環境中,你可以在該shell中呼叫指令碼中的變數!
而./first.sh 以及 sh first.sh
是在當前程式下新開一個子shell程式執行這個指令碼,當指令碼執行完畢了,sh中設定的變數和子程式一起被銷燬了!(該子shell繼承了父程式的shell的環境變數,子shell結束了變數將被銷燬,如果使用了export可以將子shell的變數反饋到父級別的shell中)。

4.更完善的指令碼構成

  • 指令碼宣告
  • 註釋資訊
  • 可執行語句
[root@localhost~]#vim /first.sh
#!/bin/bash 
#This is my first Shell-Script. 
cd /boot
echo "當前的目錄位於∶" 
pwd
echo "其中以vml開頭的檔案包括∶"   #輸出友好提示資訊
ls -Ih vml*

在這裡插入圖片描述

上述 first.sh 指令碼檔案中,第一行"#!/bin/bash"是一行特殊的指令碼宣告,表示此行以後的語句通過/bin/bash程式來解釋執行;其他以"#"開頭的語句表示註釋資訊; echo 命令用於輸出字串,以使指令碼的輸出資訊更容易讀懂。例如,執行改寫後的 first.sh 指令碼,輸出結果如下所示。

在這裡插入圖片描述

四、重定向與管道操作

1.互動式硬體裝置

  • 標準輸入:從該裝置接收使用者輸入的資料
  • 標準輸出:通過該裝置向使用者輸出資料
  • 標準錯誤:通過該裝置報告執行出錯資訊
型別裝置檔案檔案描述編號預設裝置
標準輸入/dev/stdin0鍵盤
標準輸出/dev/stdout1顯示器
標準錯誤輸出/dev/stderr2顯示器

2.重定向操作

型別操作符用途
重定向輸入<從指定的檔案讀取資料
重定向輸出>將標準輸出結果 儲存 到指定的檔案,並且覆蓋原有內容
重定向輸出>>將標準輸出結果 追加 到指定的檔案的尾部,不覆蓋原有內容
標準錯誤輸出2>將錯誤資訊 儲存 到指定的檔案,並且覆蓋原有內容
標準錯誤輸出2>>將錯誤資訊 追加 到指定的檔案的尾部,不覆蓋原有內容
混合輸出&>將標準輸出、標準錯誤儲存到同一檔案中
混合輸出2>&1將標準錯誤輸出重定向到標準輸出

For Example:

vim passwd.txt
222222
echo "123456" > passwd.txt
echo "123456" >> passwd.txt

用>表示將內容輸出到檔案中,會直接覆蓋檔案內容

在這裡插入圖片描述

在這裡插入圖片描述

用>>表示追加到檔案中,會另起一行

在這裡插入圖片描述

setenforce 0
echo "123456" > passwd.txt
passwd --stdin zs < passwd.txt

在這裡插入圖片描述

從pass.txt檔案中獲取密碼,需要注意SELinux會影響命令執行,若執行失敗可嘗試關閉後重試。

3.管道操作符號"|"

將左側的命令輸出結果,作為右側命令的輸入(處理物件),同一行命令中可以使用多個管道。

For Example:

ps aux | wc -l #顯示所有程式數

在這裡插入圖片描述

echo "abc123" | passwd --stdin zs #更改使用者zs的密碼為abc123

在這裡插入圖片描述

五、Shell變數的作用、型別

變數是會變化的值,不會變化的是常量

1.變數的作用

用來存放系統和使用者需要使用的特定引數(值)
變數名:使用固定的名稱,由系統預設或使用者定義
變數值:能夠根據使用者設定、系統環境的變化而變化

2.變數的型別

自定義變數:由使用者自己定義、修改和使用
特殊變數:環境變數、只讀變數、位置變數、預定義變數

3.自定義變數

定義一個新的變數

變數名=變數值    #變數名以字母或下劃線開頭,區分大小寫,建議全大寫

檢視變數的值

echo $變數名 #檢視當前變數的值

注意:賦值時“=”兩邊不能有空格

For Example:

在這裡插入圖片描述

4.賦值時使用引號

雙引號:允許通過$符號引用其他變數值

單引號:禁止引用其他變數值, $視為普通字元

反撇號:命令替換,提取命令執行後的輸出結果,``和$(…)作用相同

在這裡插入圖片描述

5.從鍵盤輸入內容為變數賦值

read命令獲取輸入內容

read -p 提示資訊 變數名
echo $變數名

在這裡插入圖片描述

也可用於指令碼中用於收集資訊。

For Example:

在這裡插入圖片描述

賦予指令碼執行許可權後,執行結果如下

在這裡插入圖片描述

6.變數的作用範圍

1)預設情況下,新定義的變數只在當前的Shell環境中有效,因此稱為區域性變數。當進入子程式或新的子Shell環境時,區域性變數將無法再使用。

2)可以通過內部命令export將指定的變數匯出為全域性變數,使使用者定義的變數在所有的子Shell環境中能夠繼續使用。

  • 設定變數的作用範圍表示式:
格式1:export 變數名
格式2:export 變數名=變數值

可以使用 pstree 命令檢視Shell環境,輸入 bash 命令進入子Shell環境,按Ctrl+D組合鍵或輸入 exit 命令退出子Shell環境。

在這裡插入圖片描述

輸入bash,進入子bash環境(也可稱為子Shell環境),相當於開了一個子程式。

在這裡插入圖片描述

在當前父bash環境中給PRODUCT賦值後,進入子環境,發現子環境中無法檢視PRODUCT的變數值,是因為PRODUCT並非全域性環境變數,子環境中的PRODUCT並沒有被賦值。當把PRODUCT輸出為全域性環境變數後,即使進入子Shell環境依然可以檢視父環境的變數PRODUCT的變數值。

在這裡插入圖片描述

7.整數變數的運算

  • 運算表示式
格式:expr 變數1 運算子 變數2 [運算子 變數3]
  • 常用運算子

加法 +、減法 -、乘法 \*、除法 /,取餘 %。

常用的運算表示式:

a=`expr 11 \* 2`
echo $((10 / (1+1)))
echo $[10 / (1+1)]
let i=12*4

i++ 相當於 i=$[$i+1]
i-- 相當於 i=$[$i-1]
i+=2 相當於 i=$[$i+2]

在這裡插入圖片描述

六、特殊的Shell變數

1.環境變數

由系統提前建立,用來設定使用者的工作環境
配置檔案:/etc/profile(全域性生效)、~/.bash_profile(當前使用者環境)

2.常見環境變數

PWD、PATH
USER、SHELL、HOME

使用 env 命令可以檢視到當前工作環境下的環境變數
變數USER表示使用者名稱稱,HOME表示使用者的宿主目錄,LANG表示語言和字符集,PWD表示當前所在的工作目錄,變數PATH表示可執行程式的預設搜尋路徑

3.PATH(路徑環境變數)

echo $PATH					#檢視當前搜尋路徑
PATH="$PATH:/root"			#將/root目錄新增到搜尋路徑
export PATH="$PATH:/root"	#輸出為全域性環境變數
first.sh

在這裡插入圖片描述

切換到子Shell環境依然可執行,且其他目錄下依然可執行

在這裡插入圖片描述

4.只讀變數

用於變數值不允許被修改的情況

readonly 命令設定只讀變數
readonly PRODUCT				#設定為只讀變數
echo $PRODUCT
PRODUCT=Python			        #只讀變數不可以被重新賦值
unset PRODUCT					#只讀變數不可以被刪除,unset 命令用於刪除變數,但無法刪除只讀變數,只能重啟系統解決

在這裡插入圖片描述

5.位置變數

執行指令碼sh xxx.sh 1 2 3 4 5 6 7 8 9 10…n

$n:n為數字,$0代表命令本身,1~9代表第一個到第九個引數,十以上的引數需要使用大括號表示,比如第十個引數為 ${10}

在這裡插入圖片描述

6.預定義變數

$*、$@:表示命令或指令碼要處理的引數。
  $*:把所有引數看成以空格分隔的一個字串整體,代表"$1 $2 $3 $4"。
  $@:把各個引數加上雙引號分隔成n份的引數列表,每個引數是獨立  的,代表"$1" "$2" "$3" "$4"。

$0:表示當前執行的指令碼或命令的名稱。
$#:表示命令或指令碼要處理的引數的個數。	
$?:表示前一條命令或指令碼執行後的返回狀態碼,返回值為0表示執行正確,返回任何非0值均表示執行出現異常。
也常被用於Shell指令碼中return退出函式並返回的退出值。
[root@localhost ~]#echo `date +%F` #檢視完整日期,按照年-月-日的格式輸出
2020-12-20
[root@localhost ~]#vim mybak.sh #編輯指令碼
#!/bin/bash            #表示此行以後的語句通過/bin/bash程式來解釋執行
time=backup-`date +%F`.tar.gz #把變數值backup-`date+%F`.tar.gz賦值給變數time
tar zcf $time $* &> /dev/null	#/dev/null表示的是一個黑洞檔案,通常用於丟棄不需要的資料輸出。
echo "已執行 $0 指令碼,"
echo "共完成 $# 個物件的備份"
echo "具體內容包括: $*"

[root@localhost ~]#chmod +x mybak.sh #賦予執行許可權
[root@localhost ~]#./mybak.sh /etc/passwd /etc/shadow

在這裡插入圖片描述

相關文章