系統管理中 bash shell 指令碼常用方法總結

來源:互聯網
上載者:User

標籤:

在日常系統管理工作中,需要編寫指令碼來完成特定的功能,編寫shell指令碼是一個基本功了!
在編寫的過程中,掌握一些常用的技巧和文法就可以完成大部分功能了,也就是2/8原則

1. 單引號和雙引號的區別

單引號與雙引號的最大不同在於雙引號仍然可以引用變數的內容,但單引號內僅是一般字元,不會作變數的引用,直接輸出字元竄。請看如下例子:

[[email protected] ~]# name=HaHa 
[[email protected] ~]# echo $name 
HaHa 
[[email protected] ~]# myname="$name is wow" 
[[email protected] ~]# echo $myname 
HaHa is wow 
[[email protected] ~]# myname=‘$name is wow‘ 
[[email protected] ~]# echo $myname 
$name is wow 

從上面例子可以看出,使用了單引號的時候,那麼$name只是一般字元,直接輸出而已!

2. 逐行讀取檔案
  • 使用for迴圈來讀取檔案
    for line in `cat file.txt`
    do
    echo $line
    done

注意:由於使用for來讀入檔案裡的行時,會自動把空格和分行符號作為一樣分隔字元,如果行裡有空格的時候,輸出的結果會很亂,所以只適用於行連續不能有空格或者分行符號的檔案

  • 使用while迴圈讀取檔案
    cat file.txt |while read line
    do
    echo $line
    done

    或者:

    while read line
    do
    echo $line
    done < file.txt

注意:由於使用while來讀入檔案裡的行時,會整行讀入,不會關注行的內容(空格..),所以比for讀檔案有更好的適用性,推薦使用while迴圈讀取檔案

3. bash shell 指令碼中常用隱含變數
$0 當前執行的指令碼或者命令名稱
$1-$9 代表參數的位置. 舉例 $1 代表第一個參數.
$# 指令碼調用的參數的個數
[email protected] 所有參數的內容
$* 所有參數的內容
$$ 當前運行指令碼的進程號
$? 命令執行後返回的狀態
$! 後台啟動並執行最後一個進程號
注意: $? 用於檢查上一個命令執行是否正確(在Linux中,命令退出狀態為0表示該命令正確執行,任何非0值表示命令出錯) 
$$ 變數最常見的用途是用做暫存檔案的名字以保證暫存檔案不會重複。 
$* 和 [email protected] 如果輸出是一樣的,但是在使用for迴圈,在使用 雙引號("")引用時 "$*" 會輸出成一個元素 而 "[email protected]" 會按照每個參數是一個元素方式輸出

請看測試例子

#cat test.sh 
#!/bin/sh
echo ‘"[email protected]" output.....‘
for i in "[email protected]"
do
echo $i
done
echo ‘"$*" output ....‘
for i in "$*"
do
echo $i
done

輸出結果

#sh test.sh a b c d
"[email protected]" output.....
a
b
c
d
"$*" output ....
a b c d
從輸出結果可以看出 "$*" 輸出是一行 而 "[email protected]" 輸出則是四行
4. 變數內容的刪除與替換

我們在一些情況下,需要對變數中的字元竄進行尋找刪除或者替換,就需要使用下表列出的方法

變數設定方式 說明
${變數#關鍵字} 若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最短資料刪除
${變數##關鍵字} 若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最長資料刪除
${變數%關鍵字} 若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最短資料刪除
${變數%%關鍵字} 若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最長資料刪除
${變數/舊字串/新字串} 若變數內容符合‘舊字串’則‘第一箇舊字串會被新字串取代
${變數//舊字串/新字串} 若變數內容符合‘舊字串’則‘全部的舊字串會被新字串取代

舉例如下(刪除字元竄中的某個字元):

[[email protected] ~]# export test_str="/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin" 
[[email protected] ~]# echo ${test_str#/*kerberos/bin:}
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
5. 變數條件測試賦值

在某些時刻我們需要‘判斷’某個變數是否存在,若變數存在則將此變數值賦值給新的變數,若變數不存在則將其他值賦值給新的變數.

變數設定方式 str 未定義 str 為空白字串 str 已賦值為非空字串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str?expr} expr 輸出至 stderr var= var=$str
var=${str:?expr} expr 輸出至 stderr expr 輸出至 stderr var=$str
var=${str=expr} var=expr var= var=$str
var=${str:=expr} var=expr var=expr var=$str

舉例如下:

[[email protected] ~]# test_name=""
[[email protected] ~]# test_name=${test_name-root}
[[email protected] ~]# echo $test_name
<== 因為 test_name 被設定為空白字元竄!所以當然還是保留為空白字元竄!
[[email protected] ~]# test_name=${test_name:-root}
[[email protected] ~]# echo $test_name
root <== 加上‘:’後若變數內容為空白或者是未設定,都能夠以後面的內容替換!
基本上這種變數的測試也能夠透過 shell script 內的 if...then... 來處理,不過通過上述提及的簡單的方法來測試變數,是程式看起來更精簡一些!
6. shell 中分隔字元 : 變數IFS 使用

shell指令碼中,如果使用for迴圈一個字元竄的話,預設使用空格來分割字元竄.還有前面所提到的使用for迴圈逐行讀取檔案內容時候,檔案行中如果有空格的話輸出的結果也會變亂.這個時候使用 IFS 變數來設定特定的字元竄分割符來,達到輸出正確的目的.預設情況下 IFS 是使用 , 空格 \t \n 來作為預設的分割符的.

我們將前面使用for逐行讀取檔案的例子 改進下就可以輸出正確了,請看下面

#!/bin/bash
IFS_old=$IFS #將原IFS值儲存,以便用完後恢複
IFS=$’\n’ #更改IFS值為$’\n’
for line in `cat file.txt`
do
echo $line
done

file.txt 檔案內容如下

[[email protected]]$ cat file.txt 
sdfsdfsdfsdf
ssssss ssssss ssssss sssss
sdfsdfsdfsdfsdf

執行測試程式 輸出結果如下(正確輸出)

[[email protected]]$ sh test.sh 
sdfsdfsdfsdf
ssssss ssssss ssssss sssss
sdfsdfsdfsdfsdf

如果未設定IFS變數,使用預設的IFS變數值 ,輸出結果如下

[[email protected]]$ sh test.sh 
sdfsdfsdfsdf
ssssss
ssssss
ssssss
sssss
sdfsdfsdfsdfsdf

從以上測試程式輸出結果,可以根據自己的需求來設定 IFS變數,在舉一個例子如下:

while IFS=: read userName passWord userID groupID geCos homeDir userShell
do
echo "$userName -> $homeDir"
done < /etc/passwd
7. shell 數組的使用

數組賦值方式:

(1) array=(var1 var2 var3 ... varN)
(2) array=([0]=var1 [1]=var2 [2]=var3 ... [n]=varN)
(3) array[0]=var1
arrya[1]=var2
...
array[n]=varN

計算數組元素個數或者長度:

(1) ${#array[@]} 
(2) ${#array[*]}

瞭解了數組基礎文法,舉例說明,請看:

#!/bin/bash
NAMESERVERS=("ns1.www.net." "ns2.www.net." "ns3.www.net.")
# 得到數組長度
tLen=${#NAMESERVERS[@]}

# 迴圈數組
for (( i=0; i<${tLen}; i++ ));
do
echo ${NAMESERVERS[$i]}
done

在看一個複雜一點的例子,將檔案內容讀取到數組中:

#!/bin/bash

# 設定IFS將分割符 設定為 分行符號(\n)
OLDIFS=$IFS
IFS=$‘\n‘ 

# 讀取檔案內容到數組
fileArray=($(cat file.txt))

# restore it
IFS=$OLDIFS
tLen=${#fileArray[@]}

# 迴圈顯示檔案內容
for (( i=0; i<${tLen}; i++ ));
do
echo "${fileArray[$i]}"
done
8. 邏輯判斷 條件測試
  • 檔案屬性的判斷
操作符 測試結果
-e filename 檔案存在返回1,否則返回0
-r filename 檔案可讀返回1,否則返回0
-w filename 檔案可寫返回1,否則返回0
-x filename 檔案可執行返回1,否則返回0
-o filename 檔案屬於使用者本人返回1, 否則返回0
-z filename 檔案長度為0返回1, 否則返回0
-f filename 檔案為普通檔案返回1, 否則返回0
-d filename 檔案為目錄檔案時返回1, 否則返回0

舉例如下,測試檔案是否存在:

#!/bin/bash
echo "checks the existence of the messages file."
echo -n "Checking..."
if [ -f /var/log/messages ];then
echo "/var/log/messages exists."
fi
echo
echo "...done."
  • 字串比較
操作符 比較結果
str1 = str2 當兩個字串相等時為真
str1 != str2 當兩個字串不等時為真
-n str1 當字串的長度大於0時為真
-z str1 當字串的長度為0時為真
str 當字串為非空時為真

舉例如下,比較字串來測試使用者ID :

if [ "$(whoami)" != ‘root‘ ]; then
echo "You have no permission to run $0 as non-root user."
exit 1;
fi
  • 數值比較(整數)
操作符 比較結果
num1 -eq num2 兩數相等為真
num1 -ne num2 兩數不等為真
num1 -gt num2 num1大於num2為真
num1 -ge num2 num1大於等於num2為真
num1 -lt num2 num1小於num2為真
num1 -le num2 num1小於等於num2為真

舉例如下:

num=`wc -l work.txt`
if [ $num -gt 150 ];then
echo "you‘ve worked hard enough for today."
echo
fi

如果要查看詳細的測試操作,可以查看man手冊 man test

系統管理中 bash shell 指令碼常用方法總結

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.