1. 程式人生 > >LINUX學習—bash程式設計

LINUX學習—bash程式設計

Bash特性

程序:在每個程序看來,當前主機上只存在核心和當前程序;
程序是程式的副本,程序是程式執行的例項

bash特性:
1、命令歷史,命令補全;
2、支援管道、重定向;
3、支援命令別名alias;
4、支援命令列編輯;
5、支援命令列展開;
6、支援檔名通配;
7、支援使用變數;
8、支援程式設計;
。。。

命令列編輯:
游標跳轉:
ctrl+A:跳到行首;
Ctrl+E:跳至行尾;
Ctrl+k:刪除游標至命令列尾的內容;
Ctrl+u:刪除游標至行首的內容
Ctrl+l:清屏;

命令歷史:
history:檢視命令歷史

    -c:清空命令整個歷史
    -d OFFSET [n]:刪除指定位置的命令 history -d 2010 10(表示刪除2010後位置10個歷史命令)
    -w:儲存命令歷史至歷史檔案中

命令歷史相應儲存在家目錄的.bash_history或.zsh_history隱藏檔案中
環境變數
PATH:命令搜尋路徑
HISTSIZE:命令歷史快取區大小

命令歷史的使用技巧

    !n:執行命令歷史中的第n條命令  
    !-n:執行命令歷史中倒數第n條命令  
    !!:執行上一條命令;  
    !string:執行命令歷史中最近一個以指定字串開頭的命令  
    !
$:引用前一個命令的最後一個引數; ESC, .(按ESC後鬆開再按.號):引用前一個命令的最後一個引數; ALT+.:引用前一個命令的最後一個引數; TAB:命令補全/路徑補全

路徑補全:tab鍵

命令別名:
alias CMD=’COMMAND [OPTION] [ARGUMENT]’ (有空格需要用單引號括起來)
在shell中定義的別名僅在shell的生命週期中有效:別名有效範圍為當前shell程序;要做到永久有效時需要寫到配置檔案中;
unalias CMD:撤銷命令別名

命令替換:
把命令中某個子命令替換為其執行結果的過程;
$(COMMAND) 或COMMAND

(注意是反引號): 對命令進行替換
touch ./ $(date +%F-%H-%M-%S).txt

bash支援的引號:
“(反引號):命令替換
“ “(雙引號):弱引用,可以實現變數替換
‘ ’(單引號):強引用,不完成變數替換

檔名通配, globbing(其實是命令展開,相當於檔名展開)

    *:可以用於實現任意長度任意字元 
    ?:匹配任意單個字元 ls ?e 
    [ ]:匹配指定範圍內的任意單個字元 [abc], [a-m]表示a-m中任何一個, [a-zA-Z]  
    [^]:取反,非範圍內  
    ls [a-zA-Z]*[0-9]:以字元開頭,以數字結尾的任意檔案  
    [:space:]:所以的空格(使用時還需在外面在加一箇中括號) 
    [:punct:]:標點符號  
    [:lower:]:小寫字母  
    [:upper:]:大寫字母  
    [:alpha:]:大小寫字母  
    [:digit:]:數字   
    [:alnum:]:數字和大小寫字母  
    加個^表示取反,如[^[:alpha:]]表示非字母  
    ls [[:alpha:]]*[[:digit:]]  

萬用字元有些問題並不能精確描述,導致不能匹配,此時需要用正則表示式;

man 7 glob 可檢視以上檔名通配的說明;

基礎知識

bash變數的型別:
本地變數(區域性變數)
環境變數(當前shell程序及其子程序)
位置變數:$1,$2,....
shift:輪換,輪替,前一個位置變數shift後可重複適用,shift(shift1)命令每執行一次,變數的個數($#)減一(之前的$1變數被銷燬,之後的$2就變成了$1),而變數值提前一位。同理,shift n後,前n位引數都會被銷燬。
特殊變數 :
退 1. 2. 0 255 0 1 255 1 2 , 127 #:引數的個數
@:引數列表(二者有所不同)
注意:
輸出重定向的常用技巧:
/dev/null:軟體裝置,為一個數據黑洞,一旦輸出到這則不會輸出
例:檢驗是否存在以student為名的使用者
id student &>/dev/null
echo ? 0 ,因為撤銷的是變數本身而不是變數值
unset VARNAME
檢視當shell中變數:不帶任何選項和引數,包括環境變數和本地變數
set
檢視當前shell中的環境變數
printenv
env
export

在已有變數上新增變數:(如新增環境變數)
- #在環境變數後面新增變數
export PATH=$PATH:/usr/local/apache/bin
- #在環境變數前面新增變數
export PATH=/usr/local/apache/bin:$PATH
指令碼:命令的堆砌,按實際需要,結合命令流程控制機制實現的源程式

#!/bin/bash
#註釋行,不執行
條件判斷
如果使用者不存在  
    新增使用者,給密碼並顯示新增成功;   
否則  
    顯示如果已經存在,沒有新增;   

bash中如何實現條件判斷?

一、條件測試型別:

1. 整數比較(整數測試):
-eq:測試兩個整數是否相等:比如 A e q B
-ne:測試兩個整數是否不等:不等真,相等為假
-gt:測試一個數是否大於一個數,大於為真,否則為假
-lt:測試一個數是否小於一個數,小於為真,否則為假
-ge:大於或等於
-le:小於或等於
2. 字串比較(字元測試):
==(=):測試是否相等,相等即為真(等號兩端需要空格才能比較)[ ‘ A = B’ ]
!=:測試是否為假, 不等則為真,相等為假;
>
<(大於及小於在字串測試中應用較少)
-n string:測試指定字串是為空,空則真,不空則假;
-z string:測試指定字串是否不空,不空為真,空則為加;
3. 檔案測試: 判斷檔案是否存在
-e FILE:測試檔案是否存在(即表示存在為真,不存在為假,下同)
-f FILE:測試檔案是否為普通檔案
-d FILE:測定指定路徑是否為目錄
-r FILE:測試當前使用者對指定檔案是否有讀取許可權
-w FILE:測試當前使用者對指定檔案是否有可寫許可權
-x FILE: 測試當前使用者對指定檔案是否有可執行許可權
[ -e /etc/inittab ]
4. 條件測試的表示式:
- [ expression ](注意空格)
- [[ expression ]]
- test expression
5. 組合測試條件:
-a:與關係
-o:或關係
-i:取反,非關係
if [ $# -gt 1 -a $# -le 3 ] 或者 if [ $# -gt 1 ] && [ $# -le 3 ]
6. 命令間的邏輯關係:
邏輯與:&&
如果第一個條件為假時,第二條件不用再判斷,最終結果已有:
第一個條件為真時,第二個條件必須判斷;
邏輯或:||
如果第一個條件為真,第二個條件不用判斷,最終結果已有;
如果第一個條件為假,第二個條件必須判斷才能知曉最終結果;
如果使用者user6不存在,就新增使用者user6
! id user6 && useradd user6(表示如果使用者不存在就新增)
id user6 || useradd user6 (表示如果使用者不存在就新增)
如果使用者存在,就顯示使用者已存在,否則,就新增此使用者:
id user1 && echo "user1 exists" || useradd user1
如果使用者不存在,就新增,否則,顯示其已經存在
!id user1 && useradd user1 || echo "user1 exists."
如果使用者不存在,新增並且給密碼:否則,顯示其已存在
!id user1 && useradd user1 && echo "user1" | passwd --stdin user1 || echo "user1 exists"
7. SHELL中如何進行算術運算;
A=3
B=6
1. let 算術運算表示式
let C= A + B
2. [ ] C = [ A + B]
3. ( ( ) ) C = (( A + B))
4. expr 算術運算表示式,表示式中各運算元及運算子之間要有空格,而且要使用命令引用
C= expr $A + $B
exit:退出指令碼
exit num(數字)

二、條件判斷,控制結構:

1)if判斷語句

1. 單分支if語句
if 判斷條件;then
statement1
statement2

fi

2. 雙分支if語句:
if 判斷條件;then
statement1
statement2

else
statement3
statement4

fi

3. 多分支的if語句:
if 判斷條件1;then
statement1

elif 判斷條件2;then
statement2

elif 判斷條件3;then
statement3

else
statement4

fi

給定一個路徑,判斷是否存在,存在顯示存在,否則顯示其不存在

變數名稱:
1、只能包含字母、數字下劃線,並且不能數字開頭;
2、不應該跟系統中已有的環境變數重名,否則會覆蓋值;
3、最好做到見名知義;

測試指令碼是否有語法錯誤
bash -n 指令碼名稱
bash -x 指令碼:單步執行 (可檢查每一步執行正確與否)

exit:退出指令碼
exit #
如果指令碼沒有明確定義退出狀態碼,那麼,最後執行的命令的退出碼即為指令碼的退出狀態碼:

迴圈:進入條件,退出條件
2)for while迴圈:適用於迴圈次數未知的場景,要有退出條件
語法:
1. while迴圈
while CONDITION; do
statement

done

2. for迴圈
for 變數 in 列表; do(如果do單行寫的話不需要加分號,與if中then類似)
迴圈體

done
當列表被遍歷完成之後,退出

練習:計算100以內所有正整數的和

#!/bin/bash
#
declare -i sum=0
declare -i I=1
while [ $I -le 100 ]:do
let sum+=$I
let I++
done
echo $sum

3. case語句
case語句:選擇結構

    case SWITCH in
    value1)
    statement
    ...
    ;;(每個語句都必須用雙分號結尾)
    value2)
    statement
    ...
    ;;
    *)
    statement
    ...
    ;;
    esac(結束)

如何生成列表
整數列表 {1..100}
seq [起始數] [步進長度] 結束數
declare -i SUM=0 #宣告SUM為整型
-i :integer
-x=export(環境變數)

#計算從1加到100   
declare -i sum=0
for i in {1..100};do
        let sum=`$($sum+$i)`
done
echo "the sum is $sum

寫一個指令碼:
1、設定變數FILE的值為/etc/passwd
2、依次向/etc/passwd中的每個使用者問好,並顯示對方的shell,形如:Hello, root, your shell :/bin/bash
3、統計一共有多少個使用者
for I in seq 1 $LINES;do echo “Hello, head -n $I /etc/passwd |tail -1 |cut -d: -f1” done
擴充套件:只向預設shell為bash的使用者問好

取模,取餘:%