Linux系統Bash(Shell)基礎知識(4)

  今天給大家總結一下關於bash的顏色,配置文件,變量,數組和相關shell腳本編程的基本概念;

  一.bash的顏色顯示規則

  吧是的顏色顯示,說白了就是Ascll碼對於顏色的調用設置,而在於顏色代碼當中,字符串個功能實現如下:

  \033:表示ctrl鍵;

  [:控制字符和顏色代碼之間的間隔字符;

  0m:關閉顏色屬性;

  1m:加粗顯示文本字符;

  4m:爲文本字符加下劃線標識;

  5m:使文本字符閃爍;

  7m:將背景色和前景色調換,白變黑,黑變白;

  8m:隱藏字符,將文本字符的背景色和前景色設置爲相同顏色,同爲黑或同爲白;


  30m-39m設置文本字符的前景色,即字體顏色,38m和39m暫時沒有用到;

  40m-49m:設置文本字符的背景色,即一個黑色字符的背景後是什麼顏色,48m和49m暫時沒有用到;

  前景   背景    顏色  

   30m    40m    黑色

   31m    41m    紅色

   32m    42m    綠色

   33m    43m    黃色

   34m    44m    藍色

   35m    45m    紫紅色

   36m    46m    青藍色

   37m    47m    白色

  加粗顯示文本字符

  [root@localhost wjq]# echo -e "\033[1mhello worl\033[0m"

  hello worl

  

  爲文本字符加下劃線標識

  [root@localhost wjq]# echo -e "\033[4mhello worl\033[0m"

  hello worl

  

  加粗和設置下劃線同時進行,利用“;”分隔;

  [root@localhost wjq]# echo -e "\033[1;4mhello worl\033[0m"

  hello worl


  二.配置文件

  一個完整的程序通常包含四類文件:

  二進制文件:可執行文件;

  頭文件,庫文件;

  幫助文檔;

  配置文件;

  所有在命令行進行命令的操作,只要沒有設計到文件的修改都只是在當前生命週期有效的,當關閉系統後,再開啓則無法使用;配置文件是實現數據永久顯示的基本方法,將數據的改動放入配置文件中,當系統重啓後還能重複調用,如修改alias別名放入配置文件bashrc的文本文檔當中,bashrc就是一個配置文件;

  配置文件分爲私人配置文件與通用配置文件

  通用配置文件:/etc/bashrc,/etc/profile

  私人配置文件:~/.bashrc,~/.bash_profile

          

  注意:一般情況下定義變量都是先做先用,並不需要改配置文件(聲明變量在配置文件中可能使系統出現漏洞)沒有必要就不要改;

  配置文件又分爲三類:

  profile類:

  爲交互式登陸的shell進程實現功能初始化的配置文件;

  bashrc類:

  爲非交互式登陸的shell進程實現功能啓動配置的配置文件;

  logout類:

  爲交互式登陸的shell進程提供終止及清理類功能的配置文件;


  交互式登錄:

  1.通過某個終端輸入賬號密碼來打開的shell進程;

  2.通過su - username打開的shell進程;

  非交互式登陸:

  1.在圖形界面,通過右鍵菜單打開終端的shell進程;

  2.通過su username打開的shell進程;


  profile類:

  /etc/profile

  /etc/profile.d/*.sh

  全局:在上述路徑中對配置文件進行修改,能對所有登陸的用戶進行改變;

  往往在profile文件中,如果一個配置文件中的內容過多,系統會把其切割成一個個片段,如profile.d,將切割出來的片段統

  一的存放在”程序名稱.d“目錄,在該目錄下有關於片段的所有文件大多以統一的文件名後綴來命名;

  

  ~/.bash_profile

  局部:僅針對當前家目錄的用戶,對其進行改變,不影響其他用戶;


 bashrc類:

 /etc/bashrc

 全局:可以定義對系統全部用戶有效的命令別名,本地變量,以及遮罩碼umask;

 ~/.bashrc

 局部:定義對於當前用戶有效的命令別名,本地變量,以及遮罩碼umask;


 三.變量應用

 1.字符串切片

 ${#var:}:返回變量var的字符串長度;

 ${var:offset}:返回字符串變量var的第offset個字符後面的字符串;

 ${var:offset:number}:返回字符串變量var的第offset個字符後面的number個字符;

 例

 [root@localhost wjq]# var="hello world"

 [root@localhost wjq]# echo ${#var}

 11

 返回第六個字符後的字符串

 [root@localhost wjq]# echo ${var:6}

 world

 返回第六個字符後的兩個字符串

 [root@localhost wjq]# echo ${var:6:2}

 wo

 

 2.基於模式取字串:根據不同方式取符合pattern的字符串

 ${var#*pattern}:在var字符串變量中,從左到右搜索第一個匹配字符串pattern的字符,刪除從開始到第一個匹配到pattern的所有字符;


 ${var##*pattern}:在var字符串變量中,從左到右搜索最後一個匹配字符串pattern的字符,刪除從開始到最後一個匹配到pattern的所有字符;


 ${var%pattern*}:在var字符串變量中,從右到左搜索第一個匹配到pattern的字符,刪除從開始到從右到左匹配的第一個pattern之間的所有字符;


 ${var%%pattern*}:在var字符串變量中,從右到左搜索最後一個匹配到pattern的字符,刪除從開始到從右到左最後一個匹配到的字符之間的所有字符;

 

 例

 ①

 [root@localhost wjq]# var=/etc/passwd

 [root@localhost wjq]# echo ${var#*p}

 asswd

 ②

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var##*/}"

 passwd

 ③

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var%s*}"

 /etc/pas

 [wjq@localhost ~]$ 

 ④

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var%%s*}"

 /etc/pa

 [wjq@localhost ~]$ 


 3.查找替換:利用不同方式,搜索字符串中匹配pattern的字符,並用substring字符串對其進行替換;

 ${var/pattern/substring}:在var字符串變量中,搜索第一個匹配到pattern的字符串,並用substring字符串對其進行替換;


 ${var//pattern/substring}:在var字符串變量中,搜索所有匹配到字符串pattern的字符串,並用substring字符串進行替換;


 ${var/#pattern/substring}:在var字符串變量中,搜索行首匹配到字符串pattern的字符串,並用substring字符串進行替換;


 ${var/%pattern/substring}:在var字符串變量中,搜索行尾匹配到字符串pattern的字符串,並用substring字符串進行替換;


 例

 ①

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var/e/wu}"

 /wutc/passwd

 ②

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var//s/wu}"

 /etc/pawuwuwd

 ③

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var/#\//wu}"

 wuetc/passwd

 ④

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var/%d/wu}"

 /etc/passwwu


 4.查找刪除:利用不同方式,搜索匹配到的字符串並刪除;

 ${var/pattern}:在字符串變量var中,將第一次匹配到pattern的字符串刪除;


 ${var//pattern}:在字符串變量var中,將全部匹配到pattern的字符串刪除;


 ${var/#pattern}:在字符串變量var中,將行首匹配到pattern的字符串刪除;

 

 ${var/%pattern}:在字符串變量var中,將行尾匹配到pattern的字符串刪除;


 例

 ①

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var/p}"

 /etc/asswd

 ②

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var//s}"

 /etc/pawd

 ③

 [wjq@localhost ~]$ echo "${var/#\/}"

 etc/passwd

 ④

 [wjq@localhost ~]$ echo "${var/%wd}"

 /etc/pass


 5.字符的大小寫轉換:

 ${var^^}:將字符串var變量中的所有小寫字母轉換成大寫字母;

 ${var,,}:將字符串var變量中的所有大寫字母轉換成小寫字母;


 例

 ①

 [wjq@localhost ~]$ var=/etc/passwd

 [wjq@localhost ~]$ echo "${var^^}"

 /ETC/PASSWD

 [wjq@localhost ~]$ 



 6.變量賦值:

 ${var:-value}:如果變量var爲空或未被設置,那麼直接返回value值,否則返回變量var值;


 ${var:+value}:如果變量var不爲空,則返回value,爲空則返回var;


 ${var:=value}:如果變量var爲空或者未被設置,那麼直接返回value值,並且將value值賦值給變量var,否則返回var值;


 例

 ①

 [wjq@localhost ~]$ var=//

 [wjq@localhost ~]$ echo "${var:-qq}"

 //

 [wjq@localhost ~]$ var=

 [wjq@localhost ~]$ echo "${var:-qq}"

 qq


 ②

 [wjq@localhost ~]$ var=

 [wjq@localhost ~]$ echo "${var:+qq}"

 [wjq@localhost ~]$ var=a

 [wjq@localhost ~]$ echo "${var:+qq}"

 qq


 7.變量的間接引用:

 如果第一個變量的值恰好是第二個變量的變量名,從第一個變量引用第二個變量的值的方法,就稱爲間接變量引用;

 var1=var2

 var2=value

 bash提供了兩種格式的間接變量引用方式:

 eval myvar=\$$var1==>\$var2

 myvar=$(!var1)


 四.數組

 數組:相當於幾個變量的集合,存放着一個或多個內存空間;

 在bash中只提供一維數組,並且沒有限定數組大小,利用下標存取數組中的元素,數組元素由下標0開始編號即數組的索引結點:0,1,2...,數組可以採用連續的索引結點進行賦值——稠密數組,也可以採用不連續的索引結點進行賦值——稀疏數組。

 數組名[下標]=值

 例如:

 $a[0]=beijing

 $a[1]=hainan

 $a[2]=shanghai


 數組的聲明:

 1.數組可以採用上述聲明方式逐個賦值

 2.直接對數組元素進行賦值:

 $a=("beijing" "shanghai" "tianjin")或者$a=([0]="beijing" [1]="shanghai" [3]="tianjin")

 3.利用declare命令創建數組:

 $declare -a 數組名

 

 引用數組元素:

 1.$name或${name},兩者相同,若變量未定義則用空值替換;

 2.引用固定的數組元素:${name[n]}引用索引結點爲n的值;

 3.引用整個數組的所有元素:${name[*]}或${name[@]}


 例

 [wjq@localhost ~]$ a[0]=beijing

 [wjq@localhost ~]$ echo "${a[0]}"

 beijing


 [wjq@localhost ~]$ a=("wujunqi zhengzhong shaoning")

 [wjq@localhost ~]$ echo "${a[0]} ${a[1]} ${a[2]}"

 wujunqi zhengzhong shaoning 


 查看數組的長度:

 可以通過${#name[*]}顯示出這個數組有多少個有意義的元素;

 例

 [wjq@localhost ~]$ a=(wujunqi zhengzhong shaoning)

 [wjq@localhost ~]$ echo "${#a[*]}"

 3


 數組切片:

 ${name:offset}:顯示包括offset數字所表示的索引位置及以後的所有元素,去掉從第一個數組開始的offset個數組元素

 ${name:offset:number}:顯示包括offset數字所表示的索引位置及包括offset個元素的number個元素;

 如${name:3:2}:丟棄0-2的數組變量,只取3,4數組變量;

 

 撤銷數組:

 unset array_name


 刪除數組中的元素:

 unset array_name[index]


 RANDOM變量:可以產生一組在0-32767之間的隨機變量

 例

 [wjq@localhost ~]$ echo "$RANDOM"

 16952

 [wjq@localhost ~]$ echo "$RANDOM"

 6653

 

 五.bash腳本編程

 shell腳本編程有三種:

 過程式編程語言

 腳本類編程語言

 解釋性語言

 其中腳本類編程語言在實現功能時是通過調用外部文件來實現的;

 

 過程式編程語言有三種結構,順序執行結構,選擇執行結構和循環分支結構;

 1.順序執行結構:

 根據用戶所寫的腳本命令,從左至右,從上到下按順序執行;

 

 2.選擇執行結構:

 對於某特定語句,重複執行0次,一次或多次;如if,case語句;

 if語句:

 單分支語句:

 if 測試條件

 then 命令

 fi


 雙分支語句:

 if 測試條件

 then 命令1

 else 命令2

 fi


 多分支語句:

 if 測試條件

 then 命令1

 elif 測試條件

 then 命令2

 。。。

 fi

 

 例

 計算100以內所有整數的和;

 #!/bin/bash

 #

 read -t 5 -p "Please input a integer[0]: " INTEGER

 if [ -z $INTEGER ] ; then

 INTEGER=0

 fi

 if ! echo $INTEGER | grep -q "^\<[[:digit:]]\+\>$" ; then

 echo "You must input an integer."

 exit 5

 fi


 case語句:

 可以進行多重條件選擇,相對於if,else的多分支語句,case語句的優勢就在於節約了系統所消耗的資源,其語法格式爲:

 case 變量引用 in

    模式1)

      分支1

      ;;

    模式2)

      分支2

      ;;

      ...

      *)

    默認分支

    ;;

  esac

 其執行過程是,利用變量引用所代表的值分別與各類模式進行比較,如果發現變量引用的值與某一類模式相同時,就執行該模式字符串之後的各個命令,直到遇到兩個分號結束爲止;

 case語句的模式可以匹配數字,字符串,通配符等模式;

 注意:

 ①每個模式字符串後面可有一條或多條命令,最後一條命令必須要由“;;”隔開

 ②模式字符串可以使用通配符;

 ③如果一個模式字符串包含多個模式,則應用“|”隔開;

 ④各模式字符串應唯一;

 ⑤以關鍵字esac結束;


 3.循環分支結構

 將一段代碼重複的執行0次,1次或多次;一個好的循環結構必須要包括兩個最重要的環節,即進入循環的條件:開始循環時所滿足的條件;

 退出循環的條件:

 循環結束所滿足的條件;

 shell中有三種用於循環的語句,即for,whie,until,select語句;

 for語句:

 for語句是最常用的循環結構語句。其使用方式主要有兩種,一種是值表方式,另一種是算術表達式方式;for循環特點,幾乎不會死循環,在執行循環的過程中,需要將這個LIST載入到內存當中;因此對於大列表來說可能會過多的消耗內存和cpu資源;

 值表方式

 其一般表達式爲

 for 變量 [in 值表];do 命令表;done

 ①值表可以是文件正則表達式,其格式爲:

 for 變量 in 文件正則表達式

 do

   命令表

 done

 其執行過程是,變量的值依次取當前目錄下與正則表達式相匹配的文件名,每取值一次,就進入循環體執行命令表,直至所有文件名取完爲止;

  

 bash腳本編程之用戶交互:

 位置參數變量:$1,$2,$3,...

 特殊變量:

  $#:所有位置參數的總數;

  $*:所有位置參數列表;當使用“”引用時,整個參數被當作一個字符串;

  $@:所有位置參數列表;當使用“”引用時,每個參數作爲單獨的字符串存在;

  $0:所執行腳本文件自身的路徑;

 

 ②for循環腳本也可以是全部的位置參數$#與$*

 for 變量 in $*

 do

   命令

 done

 

 ③

 for循環腳本可以直接使用純整數列表

 {1..100}:表明從1-100,中間只能爲兩點;

 for i in {1..100}

 do

   命令

 done


 seq:輸出一個整數列表

 seq [OPTION]... FIRST INCREMENT LAST

 seq 10:從1-10

 seq 5 10:從5-10

 for i in $(seq 10)

 do

   命令

 done

 

 在這裏擴充一下關於read命令的功能

 read 命令:從鍵盤上讀取數據,然後賦給指定變量;

 read [-a 數組] [-p 提示符] [-t 超時] []

 利用read命令可交互的爲變量賦值,輸入數據時,數據間以空格或製表符作爲分隔符;

 ①

 變量個數與給定數據個數相同,則依次賦值

 $read x y z

 $today is sunny

 $echo $x $y $z

 today is sunny

 ②

 變量個數少於數據個數,則從左至右賦值,但最後一個變量被賦予剩餘的所有數;

 ③

 變量個數多於數據個數,則依次對應賦值,而沒有數據與之對應的變量取空串;

 例

 在腳本中-p選項給提示信息,相當於echo

 $read -p "please enter" name

 

 -t選項5秒鐘內如果沒有進行輸入則返回,默認名字爲link;

 $read -t 5 -p "please enter[link]" name || [ -z $name] && name=link

  

 算術表達式方式:

 其一般格式爲

 for((表達式1; 表達式2; 表達式3 ))

 do

   命令表

 done

 表達式1:爲變量賦初值;

 表達式2:循環退出條件;

 表達式3:變量值的變化規律;

 如

 for((T=1;I<=100;I++));do let "sum+=I";done;echo $sum


 while語句:

 格式:

 ①while 命令;do 命令;done

 ②while CONDITION;do

   循環體

   done

   當CONDITION爲真時,進入執行循環體中的語句,直至CONDITION爲假時,跳出循環;

   例當位置參數$1存在時執行while循環

   while [ $1 ]

   do

    if [ -f $1 ]

    then

      echo "該文件爲普通文本文件"

    else

      echo "$1 is not a file"

    fi

   done


 until語句:

 格式:

 ①until 命令;do 命令;done

 ②until CONDITION;do

    循環體

  done

  當CONDITION爲假時,進入執行循環體中的語句,直至CONDITION爲真時,跳出循環;


 循環控制命令:

 continue語句:

 跳出當前循環語句,回到本層循環的開頭,進入下一輪條件判斷,若符合條件則進入下一輪循環;

 若處在多層嵌套循環中,如:

 for

   while 

      for 

        continue [3]

 跳出到最外層的循環,進行最外層循環的下一輪條件判斷,若符合則繼續循環;

 例如:

 for i in 1 2 3

 do

   if [ $i -eq 2 ]

   then

      continue

   fi

   echo "$i"

 done


 break語句:

 break語句可以使腳本從循環體中退出來,同continue相似,語法格式爲:

 break [n]

 n默認值爲1,即跳出一層循環;

 若n=3時,表示連續跳出三層循環;

 例如

 for i in $*

 do

   if [ $i -eq 5 ]

   then

       break

   else

       echo "$i"

   fi

 done

 當位置參數等於5時退出當前循環;


函數:

 由某些功能封裝在一起,在需要的時候可以直接調用,將這種封裝起來的功能體稱作爲函數;

 函數與shell程序在形式上是一致的,但是,shell程序是可以直接執行的,但函數中的語句是要通過函數調用過後才能被執行;此外,函數中的命令是在當前shell的環境中運行,而shell程序中的命令是在子shell環境中運行;

 函數應先定義之後才能被執行,可以像普通命令一樣直接使用,直接利用函數名,如show,不必帶圓括號即可調用;shell腳本與函數之間可以進行參數傳遞,函數中的$1,$2所對應的值是函數在調用時所帶的實參,還可以使用$*或$@的方式引用所有位置參數;還可以使用$#計算爲函數傳遞的參數個數;這一點與普通命令不同;函數的生命週期是從被調用開始直到遇到return結束命令或全部的命令語句執行完爲止;

 如

 show arg1 arg2

 arg1和arg2作爲函數的實參;


 函數定義格式:

 語法一:

 函數名()

 {

 命令表

 }

 語法二:

 function 函數名()

 {

  命令表

 }

 

 使用set命令可以查看所有當前shell中生效的函數;

 使用unset命令可以撤銷已經定義的函數;

 

 調用函數之後函數的返回值有兩種:

 ①函數結果的返回值

 如echo,print等輸出結果;

 ②函數狀態返回值;

 return [0];

 函數的返回值不能用exit命令,n爲退出函數時的退出值,即$?的值,n值默認時,則退出值是最後一個命令執行後的返回值;

 

 

 


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