bash編程


先介紹一下什麼是shell吧:

殼層在計算機科學中,是指“提供用戶使用界面”的軟件,通常指的是命令行界面的解析器。一般來說,這


個詞是指操作系統中,提供訪問內核所提供之服務的程序。Shell也用於泛指所有爲用戶提供操作界面的


程序,也就是程序和用戶交互的層面。因此與之相對的是程序內核,內核不提供和用戶的交互功能。 不


過這個詞也拿來指應用軟件,或是任何在特定組件外圍的軟件,例如瀏覽器或電子郵件軟件是HTML排版


引擎的shell。Shell這個詞是來自於操作系統與用戶界面的外層界面。 通常將殼層分爲兩類:命令行與圖


形界面。命令行殼層提供一個命令行界面;而圖形殼層提供一個圖形用戶界面。


bash:據我老師說的,第一次能把Hello world程序成功運行出來,你將會在學習的路上會順利一點,嘿嘿,有點小迷信了,那麼就先從Hello world程序開始吧。

 用vim編輯器編輯hello文件:

 #!/bin/bash

 # This is a simple example

   echp  Hello world

這時候該有同學問#!是什麼啊,有什麼用,/bin/bash又是什麼,

  首先,#! 是說明 hello 這個文件的類型的,有點類似於 Windows 系統下用不同文件後綴來表示不同文件類型的意思(但不相同)。Linux 系統根據 “#!” 及該字串後面的信息確定該文件的類型。


  其次,在 BASH 中 第一行的 “#!” 及後面的 “/bin/bash” 就表明該文件是一個 BASH 程序,需要由 /bin 目錄下的 bash 程序來解釋執行。BASH 這個程序一般是存放在 /bin 目錄下,如果你的 Linux 系統比較特別,bash 也有可能被存放在 /sbin 、/usr/local/bin 、/usr/bin 、/usr/sbin 或 /usr/local/sbin 這樣的目錄下。


  如何執行該程序呢?有兩種方法:一種是顯式制定 BASH 去執行:

$ bash hello 或
$ sh hello (這裏 sh 是指向 bash 的一個鏈接,“lrwxrwxrwx 1 root root 4 Aug 20 05:41 /bin/sh -> bash”)

   或者可以先將 hello 文件改爲可以執行的文件,然後直接運行它,此時由於 hello 文件第一行的 “#! /bin/bash” 的作用,系統會自動用/bin/bash 程序去解釋執行 hello 文件的:

$ chmod u+x hello
$ ./hello

  此處沒有直接 “$ hello”是因爲當前目錄不是當前用戶可執行文件的默認目錄,而將當前目錄“.”設爲默認目錄是一個不安全的設置。

  需要注意的是,BASH 程序被執行後,實際上 Linux 系統是另外開設了一個進程來運行的。


bash特性之命令別名和命令引用

        alias

alias ALIAS=COMMAND

示例:     

[root@stu31 ~]# alias ls='ls -la'

[root@stu31 ~]# ls /tmp/

total 80

drwxrwxrwt.  5 root root  4096 Aug  3 12:19 .

dr-xr-xr-x. 27 root root  4096 Aug  3 11:12 ..

drwxr-xr-x   2 root root  4096 Jul 28 14:58 dangerous

-rw-------   1 root root     0 Jul 28 10:04 grub-install.img.504t6u

-rw-------   1 root root   401 Jul 28 10:04 grub-install.log.fPXD9g

drwxrwxrwt   2 root root  4096 Aug  3 11:12 .ICE-unix

-rwx------.  1 root root  1118 Jul 28 09:11 ks-script-0C1VlZ

-rwxr-xr-x.  1 root root    67 Jul 28 09:11 ks-script-0C1VlZ.log

drwxr-xr-x   2 root root 53248 Jul 28 14:48 test

-rw-------.  1 root root     0 Jul 28 08:47 yum.log

        別名與命令同名時,要使用絕對路徑,\COMMAND生效範圍:命令行定義的別名,其生效範圍爲當前會話;

        

         unalias [ALIAS]

 -a: 撤消所有別名

示例:

[root@stu31 ~]# unalias ls

[root@stu31 ~]# ls /tmp/

dangerous grub-install.log.fPXD9g  ks-script-0C1VlZ.logyum.log

grub-install.img.504t6u  ks-script-0C1VlZ  test

         

          bash支持的引用:

''

""

``:引用一個命令的執行結果

示例:

1alias ls='ls --color=auto' #輸出顯示爲彩色

2[root@stu31 /]# cd `who am i`

 [root@stu31 ~]# 


bash特性之文件名通配(globbing):

            ?:匹配任意字符

            *:匹配任意長度任意字符

             例:*a *b a*b *a*b*

           []:匹配指定範圍內的任意單字符

             例:[a-z];[0-9];[a-z0-9]

            [^]:匹配指定範圍意外的任意單字符

             例:[^0-9]

             字符集合:                     

                        [:space:] : 所有空白字符

[:punct:] : 所有標點符號

[:lower:] :所有小寫字母

[:upper:] :所有大寫字母

[:digit:] :所有數字

[:alnum:] :所有大小寫字母和數字

[:alpha:] :所有字母

示例:顯示/etc目錄下,以非字母開頭,文件或目錄;

# ls -d /etc/[^[:alpha:]]*


bash之快捷鍵:

        Ctrl+a: 跳轉至命令行首

        Ctrl+e: 跳轉至命令行尾

        Ctrl+u: 刪除命令行首至當前光標所在處之前的所有內容

        Ctrl+k: 刪除當前光標所在處至命令行尾的所有內容

        Ctrl+l: 清屏

        Ctrl+c: 中止或取消

        Ctrl+z: 把當命令送至後臺


bash之bash變量:

               bash變量類別:

本地變量:只對當前shell進程有效的變量;對其它shell進程無效,包當前                                   shell進程的子進程;

  VAR_NAME=VALUE

  變量賦值:向變量的存儲空間保存數據

                                 示例:

                                     [root@stu31 ~]# a=1

                                     [root@stu31 ~]# b=2

                                     

                                     [root@stu31 ~]# echo $a

                                      1

                                     [root@stu31 ~]# echo $b

                                       2

  變量引用:${VAR_NAME}

"":弱引用,裏面的變量會被替換;

'':強引用,裏面的所有字符都是字面量,直接輸出;

                          

                          環境變量:對當前shell進程及其子shell有效,對其它的shell進程無效;

定義:export VAR_NAME=VALUE

導出:export VAR_NAME

用戶可自義環境變量

bash有許多內置的環境變量

撤消變量:unset VAR_NAME

只讀變量:readonly VAR_NAME


局部變量:

對shell腳本中某代碼片斷有效;通常用於函數本地;

local VAR_NAME=VALUE


位置變量:

$1, $2, ..., ${10}


                        查看當前shell進程中的所有變量:set

                        查看當前shell進程中的所有環境變量:export, printenv, env

                        變量命名:

               1、不能使用程序中的關鍵字(保留字);

               比如:if, case, for

               2、只能使用數字、字母和下劃線,且不能以數字開頭;

               3、要見名知義

                  File


                       變量類型:

                      name=Jerry

                     1、存儲機制

                     2、存儲空間

                     3、參與的運算方式


                     變量類型:

                     數值型:

                     精確數值:整數

                     近似數值:浮點型

                     單精度浮點

                     雙精度浮點

                     字符型:

                           char

                           string

                    布爾型:

                          true, false


                         類型轉換:

                         顯式轉換

                         隱式轉換


            bash是弱類型的語言:一切皆字符


bash之bash的配置文件

              profile類:爲交互式登錄的用戶提供配置

      全局:

  /etc/profile

  /etc/profile.d/*.sh

       用戶:

  ~/.bash_profile


        功用:

    1、設定環境變量

    2、運行命令或腳本


                bashrc類:爲非交互式的用戶提供配置

                全局:

            /etc/bashrc

                用戶:

            ~/.bashrc


                功用:

            1、設定本地變量

            2、定義命令別名


               登錄類型:

                交互式:

                直接通過終端輸入賬號和密碼登錄;

               使用su -l USERNAME 或 su - USERNAME;

 

                非交互式:

                 su USERNAME

                 圖形界面下打開的終端

                 執行腳本


    通過編輯配置文件修改的配置生效?

      1、退出並重新登錄;

      2、讓bash重讀此配置文件;

. FILE

source FILE


交互登錄的用戶:

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc


非交互登錄的用戶:

~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh


bash之bash編程:

                 特殊變量:

                          $#,$*: 傳遞給腳本參數的個數

                          $@:引用傳遞給腳本的所有參數

                          $?:狀態返回值

                 bash的循環語句:

                              for

                              while 

                              until

                              for語句格式:

                                          for 變量 in 列表 ;do

                                             執行的命令

                                          done  

                                          (退出條件:遍歷結束)  

                             

                           for的第二種使用格式 :

                       for ((初始條件;測試條件;修改表達式)); do

循環體

done

例:for file in `ls`;do echo $file;done

  創建十個文件夾file1-file10                              

#!/bin/bash

for fileName in {1..10};do

touch file$(fileName)
done

計算100以內所有正整數之和
#!/bin/bash
#
declare -i sum=0

for ((counter=1;$counter <= 100; counter++)); do
let sum+=$counter
done
echo $sum

                              

                              while語句格式:                                            

                                                                             while 條件; (注:只要特定條件爲真,”while” 語句就會執行)

                                                                             do

                                                                                     語句 

                                                                              done

示例:                                                                                   

#!/bin/bash
COUNTER=0  
while [  $COUNTER -lt 10 ]; do  
    echo The counter is $COUNTER  
    let COUNTER=COUNTER+1   
done

          

                               until語句格式:              

                                                                           until 條件; (注:只要特定條件爲假,”while” 語句就會執行)

                                                                             do

                                                                                     語句 

                                                                              done

示例:

#!/bin/bash
myvar=1
until [ $myvar -gt 10 ]do
     echo $myvar
myvar=$(( $myvar + 1 ))
done

              

                              生成列表的方式:

         1、手動給個列表:

    for i in 1 2 3 4 5;

         2、數值列表:

    {start..end}

     `seq [start [increment]] end`

         3、$*, $@

         4 、命令生成列表

示例:

顯示/etc/passwd文件中位於文件的第偶數行的用戶名;並顯示共有多少個這樣的用戶;
#!/bin/bash
#
totalUsers=`wc -l /etc/passwd | cut -d' ' -f1`

for i in `seq 2 2 $totalUsers`; do
             userName=`head -n $i /etc/passwd | tail -1 | cut -d: -f1`
    echo $userName >> /tmp/passwd.tmp
    echo $userName
done

users=`wc -l /tmp/passwd.tmp | cut -d' ' -f1`
echo "Total users: $users."

 

bash之bash如何實現算術運算:                                                                                          

            變量:弱類型


            如何定義整型變量:

       let VAR_NAME=INTEGER_VALUE

例如:let a=1

        declare -i VAR_NAME=INTEGER_VALUE

例如:declare -i a=3


注意:即使沒有定義爲整型變量,字符型的數字依然可以參與算術運算;bash會執行變量類型的隱式類型轉換;


          實現算術運算的方式:

let VAR_NAME=ARITHMATIC_EXPRESSION

VAR_NAME=$[ARITHMATIC_EXRESSION]

VAR_NAME=$((EXPRESSION))

VAR_NAME=$(expr $num1 + $num2)


算術運算符:

+

-

*

/

%:取模,取餘數

5%2=1, 

**: 2**3 (這是次方運算,2的3次方)

示例:
分別計算100以內所有偶數之和和奇數之和;
#!/bin/bash
#
declare -i evensum=0
declare -i oddsum=0

for i in `seq 1 2 100`; do
  oddsum=$[$oddsum+$i]
done

for j in `seq 2 2 100`; do
  evensum=$[$evensum+$j]
done

echo "evensum: $evensum, oddsum: $oddsum."

寫一個腳本
1、腳本可以接受一個以上的文件路徑作爲參數;
2、顯示每個文件所擁有的行數;
3、顯示本次共對多少個文件執行了行數統計;
4、顯示所有文件的總行數;

#!/bin/bash
#
declare -i totalLines=0
declare -i noFiles=0

for file in $*; do
curFileLines=`wc -l $file | cut -d' ' -f1`
echo "$file has $curFileLines."
let noFiles++
let totalLines+=$curFileLines
done
echo "Total Files: $noFiles."
echo "Total Lines: $totalLines."


                        bash弱類型:

                   變量=值

           任何無需事先聲明,可直接使用

           值默認都是字符型

           a=abc, b=3

           a=3

           賦值:

       a=4

           增強型賦值:

              +=, -=, *=, /=, %=

              a=$[$a+1] 相當於 let a+=1


自加:var++, var--, ++var, --var

          export PATH=$PATH:/usr/local/apache/bin

          unset: 撤消 

                                算術運算:bash會對數字執行隱式的類型轉換

                let VAR_NAME=Integer_Value

                 declare -i Var_Name=Integer_Value


           操作符:

         +, -, *, /, %, **

雙目運算符:需要至少兩個操作數


              bash的算術運算的方式:

                          let Var_Name=EXPRESSION

                          $[EXPRESSION]

                          $((EXPRESSION))

                          命令:expr ARG1 OP ARG2

例:計算100內的所有正整數的和            
                       #!/bin/bash
                        declare -i sum=0
for i in {1..100}; do
let sum+=$i
done

echo $sum

                      

                  邏輯運算:

                  布爾運算:真,假

                  與、或、非、異或

                  與運算:

                        真,假:

                        真 && 真 = 真

                        真 && 假 = 假

                        假 && 真 = 假

                        假 && 假 = 假


                       或運算:

                         真,假

                         真 || 真 = 真

                         真 || 假 = 真

                         假 || 真 = 真

                         假 || 假 = 假


                         非運算:

                          真,假

                            !真=假

                            !假=真


命令都有其狀態返回值:

成功:0,真

失敗:1-255, 假

                                    

                          bash條件測試:

                       命令執行成功與否即爲條件測試

                test EXPR

                [ EXPR ]

                ` EXPR `


                       比較運算:

                        >, <, >=, <=, ==, !=


            測試類型:根據比較時的操作數的類型

            整型測試:整數比較

            字符測試:字符串比較

            文件測試:判斷文件的存在性及屬性等


(注意:比較運算通常只在同一種類型間進行)


            整型測試:

              -gt: 大於 

              -lt: 小於

              -ge: 大於等於

              -le: 小於等於

              -eq: 等於

              -ne: 不等於


             字符串測試:

                雙目

               >: [[ "$string1" > "$string2" ]]

               <:

               >=

               <=

               ==

               !=


                單目:

                  -n String: 是否不空,不空則爲真,空則爲假

                  -z String: 是否爲空,空則爲真,不空則假

    

bash之bash選擇:

                

               if: 三種使用格式

           單分支的if語句:

          if 測試條件; then

            選擇分支

           fi

表示條件測試狀態返回值爲值,則執行選擇分支;

                           

          雙分支的if語句:

          if 測試條件; then

           選擇分支1

          else

   選擇分支2

           fi

兩個分支僅執行其中之一。


                          多分支的if語句:

          if 條件1; then

       分支1

          elif 條件2; then

       分支2

          elif 條件3; then

       分支3

               ...

          else

      分支n

          fi

                    

例:1寫一個腳本,接受一個參數,這個參數是用戶名;如果此用戶存在,則顯示其ID號;
      #!/bin/bash
      if ! id $username &> /dev/null; then
    useradd $username
       fi
       
       
           
2通過命令行給定一個文件路徑,而後判斷:
如果此文件中存在空白行,則顯示其空白行的總數;
否則,則顯示無空白行;
#!/bin/bash
if grep "^[[:space]]*$" $1 &> /dev/null; then
echo "$1 has $(grep "^[[:space]]*$" $1 | wc -l) blank lines."
else
echo "No blank lines"
fi       
       
       
       
3傳遞一個用戶名給腳本:
如果此用戶的id號爲0,則顯示說這是管理員
        如果此用戶的id號大於等於500,則顯示說這是普通用戶
否則,則說這是系統用戶;

#!/bin/bash

if [ $# -lt 1 ]; then
        echo "Usage: `basename $0` username"
        exit 1
fi

if ! id -u $1 &> /dev/null; then
echo "Usage: `basename $0` username"
echo "No this user $1."
exit 2
fi

if [ $(id -u $1) -eq 0 ]; then
echo "Admin"
elif [ $(id -u $1) -ge 500 ]; then
echo "Common user."
else
echo "System user."
fi

                      

                   bash字串測試中的模式匹配:

                    [[ "$var" =~ PATTERN ]]

例:讓用戶給定一個用戶名,判斷其是否擁有可登錄shell;
#!/bin/bash
#
read -p "Plz input a username: " userName
userInfo=`grep "^$userName\>" /etc/passwd`

if [[ "$userInfo" =~ /bin/.*sh$ ]]; then
echo "can login"
else
echo "cannot login"
fi

                       

bash之case語句:

                 一般,case語句和if一起使用,但是隻要你面臨可能採取的一系列不同的動作時,你可能迷惑,要處理複雜條件時,你可以考慮一下case語句

                                        case表達式:

                                             case EXPRESSION in 

                                             CASE1) COMMAND-LIST;;

                                             CASE2) COMMAND-LIST;; 

                                              ... 

                                             CASENCOMMAND-LIST;; 

                                             esac

每個分支是一個符合pattern的表達式,在COMMAND-LIST中首先符合的命令就執行該條,沒個case語句以esac結束

例:
#!/bin/bash
# 1.) Open file 2.) Display file 3.) Edit file 4.) Delete file
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "---------------------------------"
echo "List of item to operate file -"
echo "---------------------------------"
echo "1). Open a file -"
echo "2). Display a file -"
echo "3). Edit a file -"
echo "4). Delete a file -"
echo "---------------------------------"
read select
case $select in
1)
echo "do open file operation"

2)
echo "do display a file operation"

3)
echo "do edit a file operation"

4)
echo "do delete a file operation"

*)
echo "There is nothing to do!"
exit 1

esac


bash之數組:

          1,聲明一個數組

               declare -i array

          2,數組賦值

                (1) array=(a1 a2 a3 ... aN)

              (2)array=([0]=a1 [2]=a2 [3]=a3 ... [n]=aN)

          (3)array[0]=a1  array[1]=a2 array[2]=a3 ... array[n]=aN                               

          3,數組複製:

要使用${ARRAY[@]}

$@: 每個參數是一個獨立的串

$*: 所有參數是一個串

               

          4,引用數組

              echo ${array[n]}

          5,數組的訪問:

用索引訪問:

ARRAY[index]

          6,從數組中挑選某元素:

${ARRAY[@]:offset:number}

切片:

offset: 偏移的元素個數

number: 取出的元素的個數


${ARRAY[@]:offset}:取出偏移量後的所有元素


${ARRAY[@]}: 取出所有元素

  

          7,從數組中刪除元素:

              unset ARRAY[index]

例:將字串裏的字母逐個放入數組中並輸出
#!/bin/bah
chars='qazwsx'
for((i=0;i<=6;i++));do
   array[$i]=${chars:$i:1} (表示從chars字符串的 $i 位置開始,獲取 1 個字符)
   echo ${array$[$i]}
done
複製一個數組中下標爲偶數的元素至一個新數組中
#!/bin/bash
declare -a mylogs
logs=(/var/log/*.log)

echo ${logs[@]}

for i in `seq 0 ${#logs[@]}`; do
if [ $[$i%2] -eq 0 ];then
index=${#mylogs[@]}
mylogs[$index]=${logs[$i]}
fi
    done

echo ${mylogs[@]}


祝大家看的愉快j_0028.gif



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章