1. 程式人生 > >shell淺談之一變數和引用

shell淺談之一變數和引用

一、簡介

       變數是指令碼語言的核心,shell指令碼又是無型別的。變數本質上儲存資料的一個或多個計算機記憶體地址,分為本地變數(使用者當前shell生命期使用,隨shell程序的消亡而無效,類似區域性變數)、環境變數(適用於所有由登入程序所產生的子程序)和位置引數(向shell指令碼傳遞引數,只讀)。而shell使用變數就需要引用,它們密切相關。

二、詳解

1、變數賦值

(1)變數賦值規則:等號兩邊不能有空格、value值包括空格必須用雙引號、變數名只能包括字母數字和下畫槓,並變數名不能以數字開頭。

(2)如果value值中有空格,需要用雙引號引以來。variable="hello world"。

(3)unset命令清除變數的值。

(4)變數賦值模式

(5)readonly將變數設定為只讀,只讀變數不能再次進行賦值操作。

2、無型別的變數

(1)C中定義變數需要宣告整型、浮點型、字元型等,而shell指令碼變數卻是無型別的。shell不支援浮點型只支援整型和字元型,同時字元型還具有一個整型值0(判斷標準:變數中只包含數字是數值型其他是字串)。

  1. #!/bin/bash
  2. a=2009  
  3. let "a+=1"
  4. echo "a=$a"
  5. b=xx09  
  6. echo "b=$b"
  7. declare -i b  
  8. echo "b=$b"
  9. let "b+=1"
  10. echo "b=$b"
  11. exit 0  

(2)位置引數

從命令列向shell指令碼傳遞引數,$0表示指令碼的名字,$1代表第一個引數,以此類推。從${10}開始引數號需要用花括號括起來。

  1. #!/bin/sh
  2. echo "The script name is: $0"            #$0表示指令碼本身  
  3. echo "Parameter #1:$1"
  4. echo "Parameter #2:$2"
  5. echo "Parameter #3:$3"
  6. echo "Parameter #4:$4"
  7. echo "Parameter #5:$5"
  8. echo "Parameter #6:$6"
  9. echo "Parameter #7:$7"
  10. echo "Parameter #8:$8"
  11. echo "Parameter #9:$9"
  12. echo "Parameter #10:${10}"           #用大括號括起來  
  13. echo "-------------------------"
  14. echo "All the command line parameters are: $*"
特殊的位置引數:

3、內部變數

內部變數指能夠對bash shell指令碼行為產生影響的變數,屬於環境變數的範疇。

(1)BASH

      BASH記錄了shell的路徑,通常是/bin/bash。內部變數SHELL是通過BASH的值確定當前Shell的型別,linux使用的是bash shell,因而兩個變數的值都是/bin/bash。

(2)BASH_VERSINFO

它是一個包含6個元素的陣列,這些元素用於表示bash的版本資訊。

  1. #!/bin/bash
  2. for n in 0 1 2 3 4 5  
  3. do
  4.   echo "BASH_VERSINFO[$n]=${BASH_VERSINFO[$n]}"
  5. done  

BASH_VERSINFO[0]表示bash shell的主版本號,BASH_VERSINFO[1]表示shell的次版本號,BASH_VERSINFO[2]表示shell的補丁級別,BASH_VERSINFO[3]表示shell的編譯版本,BASH_VERSINFO[4]表示shell的發行狀態,BASH_VERSINFO[5]表示shell的硬體架構。

(3)BASH_VERSION

linux系統的bash shell版本包含主次版本、補丁級別、編譯版本和發行狀態,即BASH_VERSINFO陣列取值為0~4。顯示BASH_VERSION的值。


(4)DIRSTACK
      它顯示目錄棧的棧頂值。linux目錄棧用於存放工作目錄,便於程式設計師手動控制目錄的切換,bash shell定義了兩個系統命令pushd(將某目錄壓入目錄棧並將當前工作目錄切換到入棧的目錄)和popd(將棧頂目錄彈出並將當前工作目錄切換到棧頂目錄)來維護目錄棧。

      DIRSTACK記錄棧頂目錄值,初值為空。linux還有一個命令dirs用於顯示目錄棧的所有內容。

(5)GLOBIGNORE

     它是由冒號分隔的模式列表,表示通配時忽略的檔名集合。一旦GLOBIGNORE非空,shell會將通配得到的結果中符合GLOBIGNORE模式中的目錄去掉。例如ls a*列出當前目錄以a開頭的檔案,設定GLOBIGNORE=“ar*”,再次執行ls a*將剔除以ar開頭的檔案。

(6)GROUPS

      GROUPS記錄了當前使用者所屬的群組,linux的一個使用者可同時包含在多個組內,GROUPS是一個數組記錄了當前使用者所屬的所有群組號。管理使用者組的檔案是/etc/group,格式:群組名:加密後的組口令:群組號:組成員,組成員(組成員列表)。

(7)HOSTNAME

      HOSTNAME記錄了主機名,linux主機名是網路配置時必須要設定的引數,可在/etc/sysconfig/network檔案中設定主機名。/etc/hosts檔案用於設定IP地址和主機名之間的對應關係,可快速從主機名查詢IP地址。

(8)HOSTTYPE和MACHTYPE

都用於記錄系統的硬體架構,它們與BASH_VERSINFO[5]等值


(9)OSTYPE

記錄作業系統型別,linux系統中,$OSTYPE=linux。

(10)REPLY

      REPLY變數與read和select命令有關。read用於讀取標準輸入(stdin)的變數值,read variable將標準輸入儲存到variable變數中,而read將讀到的標準輸入儲存到REPLY變數中。

     select指令碼:

  1. #!/bin/bash
  2. echo "Pls. choose your profession?"
  3. select var in "Worker""Doctor""Teacher""Student""Other"
  4. do
  5.    echo "The \$REPLY is $REPLY."
  6.    echo "Your preofession is $var."
  7. break
  8. done  

”#?"提示符由shell提示符變數PS3進行設定(#?是其預設值)。修改export PS3="your choice:"。REPLY變數值為使用者選擇的序號,var變數為REPLY序號所對應的字串。

(11)SECONDS

SECONDS記錄指令碼從開始執行到結束所耗費的時間(單位為秒)。除錯效能時比較有用。

  1. #!/bin/bash
  2. count=1  
  3. MAX=5  
  4. while [ "$count" -le "$MAX" ];do
  5.   echo "This is the $count time to sleep."
  6.   let count=$count+1  
  7.   sleep 1  
  8. done  
  9. echo "The running time of this script is $SECONDS"

(12)SHELLOPTS

它記錄了處於開狀態的shell選項列表,它是一個只讀變數。Shell選項用於改變Shell的行為,Shell選項有開和關兩種狀態,set命令用於開啟或關閉選項。set -o optionname(開啟名為optionname選項),set +o optionname(關閉名為optionname選項)。比如開啟interactive(互動模式執行)可以使用set -o interactive或set -i等價。Shell選項有很多。

(13)SHLVL

       記錄Shell巢狀的層次,啟動第一個shell時,$SHLVL=1,若在這個Shell中執行指令碼,指令碼中的SHLVL為2,指令碼中再執行子指令碼,SHLVL就會遞增。

(14)TMOUT

用於設定Shell的過期時間,TMOUT不為0時,shell會在TMOUT秒後將自動登出,TMOUT放在指令碼中可以規定指令碼的執行時間。

  1. #!/bin/bash
  2. TMOUT=3  
  3. echo "What is your name?"
  4. read fname  
  5. if [ -z "$fname" ]; then  
  6.    fname="(no answer)"
  7. fi  
  8. echo "Your name is $fname"

使用者有輸入,指令碼執行read後的程式,使用者沒有輸入等待TMOUT秒後執行read後程序但fname會為空。

4、有型別變數

    Shell變數一般是無型別的,bash shell提供了declare和typeset兩個命令用於指定變數的型別(它們完全等價)。declare [選項] 變數名,有6個選項。

declare命令-r選項將變數設定成只讀屬性,與readonly命令一樣,變數值不允許修改。

declare命令-x選項將變數宣告為環境變數,相當於export,但declare -x允許宣告環境變數同時給變數賦值,而export不支援。

declare -i將變數定義為整型數,不能再按字串形式處理改變數(和let命令進行算術運算一樣,expr命令可以替換let命令)。

  1. #!/bin/bash
  2. variable1=2009  
  3. variable2=$variable1+1  
  4. echo  "variable2=$variable2"
  5. let variable3=$variable1+1  
  6. echo  "variable3=$variable3"
  7. declare -i variable4  
  8. variable4=$variable1+1  
  9. echo  "variable4=$variable4"

      再介紹一種變數執行算術運算的方法:雙圓括號即((...))格式。result=$((var1*var2));var1和var2執行乘法運算。雙圓括號也可以使shell實現C語言風格的變數操作。
  1. #!/bin/bash
  2. ((a = 2014))  
  3. echo "The initial value of a is:$a"
  4. ((a++))  
  5. echo "After a++,the value of a is:$a"
  6. ((++a))  
  7. echo "After ++a,the value of a is:$a"
  8. ((a--))  
  9. echo "After a--,the value of a is:$a"
  10. ((--a))  
  11. echo "After --a,the value of a is:$a"

      雙圓括號實現五種C語言風格的運算,自增自減是shell算術運算子中未曾定義過的,是C語言中的相關內容。a = 2014,C語言允許賦值兩端有空格但shell不允許。雙圓括號還可以實現更加複雜的C語言的運算如邏輯判斷、三元操作等。

5、間接變數引用

      該引用不是將變數引起來,而是理解為:如果第一個變數的值是第二個變數的名字,從第一個變數引用第二個變數的值就稱為間接變數引用。bash shell提供了兩種格式實現間接變數引用:eval tempvar=\$$variable和tempvar=${!variable},其中eval是關鍵字,用\$$形式得到variable的簡介引用,用${!...}得到variable的間接引用。
  1. #!/bin/bash
  2. variable1=variable2  
  3. variable2=Hadoop  
  4. echo "varialbe1=$variable1"
  5. eval tempvar=\$$variable1  
  6. echo "tempvar=$tempvar"
  7. echo "Indirect ref variable1 is :${!variable1}"

例:使用間接變數引用實現資料庫表格的查詢:
  1. #!/bin/bash
  2. S01_name="Li Hao"
  3. S01_dept=Computer  
  4. S01_phone=025-83481010  
  5. S01_rank=5  
  6. S02_name="Zhang Ju"
  7. S02_dept=English  
  8. S02_phone=025-83466524  
  9. S02_rank=8  
  10. S03_name="Zhu Lin"
  11. S03_dept=Physics  
  12. S03_phone=025-83680010  
  13. S03_rank=3  
  14. PS3='Pls. select the number of student:'
  15. select stunum in "S01""S02""S03"
  16. do
  17.   name=${stunum}_name  
  18.   dept=${stunum}_dept  
  19.   phone=${stunum}_phone  
  20.   rank=${stunum}_rank  
  21.   echo "BASIC INFORMATION OF NO.$stunum STUDENT:"
  22.   echo "NAME:${!name}"
  23.   echo "DEPARTMENT:${!dept}"
  24.   echo "PHONE:${!phone}"
  25.   echo "RANK:${!rank}"
  26.   break
  27. done  
      在間接變數引用中,第一個變數中存放的是最終值的地址,因此,間接變數引用使得shell程式設計實現了類似於C語言中指標的功能,在很多場合能夠精簡shell指令碼。

6、引用

(1)引用指將字串用引用符號引起來,以防止特殊字元被shell指令碼重解釋為其他意義。shell中定義了四種引用符號。

(2)雙引號和單引號

       雙引號引用除美圓符號($)、反引號(`)和反斜線(\)之外的所有字元,即$和`及\在雙引號中仍被解釋為特殊意義,利用雙引號引用變數能防止字串分割,而保留變數中的空格。因此雙引號的引用方式稱為部分引用。


        單引號中字元除單引號本身之外都解釋為字面意義,不再具備引用變數的功能,單引號的引用方式稱為全引用。

  1. #!/bin/bash
  2. echo "Why can't I write 's between single quotes"
  3. echo 'Why can'"'"'t I write' "'"'s between single quotes'
(3)反引號

反引號進行命令替換(將命令的標準輸出作為值賦給某個變數),等價於$(),同時$()形式的命令替換是可以巢狀的。如`pwd`和$(pwd)等價都為當前工作目錄。

反引號與$()在處理雙反斜線時存在區別,反引號將反斜線符號處理為空格,而$()符號將其處理為單斜線符。


7、轉義

(1)反斜線符號(\)表示轉義,將遮蔽下一個字元的特殊意義,而以字面意義解析它。


  1. #!/bin/bash
  2. variable="(]\\{}\$\""
  3. echo $variable  
  4. echo "$variable"
  5. IFS='\'
  6. echo $variable  
  7. echo "$variable"
  8. exit 0  

(2)轉義符除了遮蔽特殊字元的特殊意義外,加上一些字母能夠表達特殊的含義。

  1. #!/bin/bash
  2. #echo不加e選項,按照字面含義解釋\t等特殊符號
  3. echo "\t\n\a\v"
  4. #echo加上e選項後,按照特殊含義解釋這些特殊符號
  5. echo -e "\t\t\t\thello"
  6. echo $'\t\thello'
  7. echo -e "hello\v\v\v\vhello"
  8. echo -e "\a\a\a\a"
  9. echo -e "\042"

$''與-e選項等價

(3)echo加-n選項表示輸出文字後不換行,不帶-n預設是輸出文字後自動換行。

三、總結

(1)從shell的基礎開始瞭解,一步步向上走。

(2)可發郵件溝通,相互提高!郵箱地址[email protected]

相關推薦

shell之一變數引用

一、簡介        變數是指令碼語言的核心,shell指令碼又是無型別的。變數本質上儲存資料的一個或多個計算機記憶體地址,分為本地變數(使用者當前shell生命期使用,隨shell程序的消亡而無效,類似區域性變數)、環境變數(適用於所有由登入程序所產生的子程序)和位置

值型別引用型別在堆棧中的儲存一

首先,讓我們來簡單瞭解一下什麼是“棧”(stack),什麼是“堆”(heap)。“棧”其實就是一種後入先出(LIFO)的資料結構。在我們.NET Framework裡面,由CLR負責管理,我們程式設計師不用去擔心垃圾回收的問題;每一個執行緒都有自己的專屬的“棧”。“堆”的存

shell變數引用

shell中,變數的命名:可以有字母、數字和下劃線組成,並且只能以字母和下劃線開頭。 shell語言的系統變數主要在對引數判斷和命令返回值判斷是使用。其中,包括指令碼和函式的引數、指令碼和函式的返回值

shell程式設計——變數引用

1    在shell中,通常情況下使用者可以直接使用變數,無需先進行定義,當用戶第一次    使用某個變數時,實際上就同時定義了這個變數,在變數的作用域內,使用者都可以使用該變數。在shell語言中,如果變數的值包含空格,則一定要使用引號引用起來。 為了更好地控制變數的相關

String,StringBufferStringBuilder的區別

操作 ringbuf builder 多個 比較 build 序列 不可變 存在 一、名詞解釋   String:字符串,並且是不可變對象;   StringBuffer和StringBuilder:字符串,並且是可變的字符序列。 二、速度比較   因為StringBuff

用戶名權限

width chmod 保留 chown 執行 用戶添加 附加 -o 指定 小編已經寫了幾篇文章了,卻忘了自我介紹,咳咳咳(隆zhuang重qiang介zuo紹shi)一下:翠衣薄紗如花艷,柳眉鳳眼俏佳人說的就是我!不扯了其實,小編擁有一個四口之家,那麽小編今天就借家獻

IP地址子網掩碼的對應關系,以及2進制10進制詳解!

2進制和10進制詳解!大家好,我是帶你們成長的凡凡~IP地址的結構: #長度為 32 bit;先 #結構 - 網絡位 + 主機位子網掩碼: -作用 區分IP地址中的網絡位與主機位 必須與IP地址,一一對應,成對出現; -表示 純2進

【ASP.NET MVC系列】表單HTML輔助方法

繼承 好的 內容 概述 調用 復制 畫圖 models pac 【01】淺談Google Chrome瀏覽器(理論篇) 【02】淺談Google Chrome瀏覽器(操作篇)(上) 【03】淺談Google Chrome瀏覽器(操作篇)(下) 【04】淺談AS

VI設計畫冊需考慮的三大塊

VI設計產品的VI設計和畫冊設計該要怎麽做?想要做好VI設計或畫冊設計只需從以下這些方面的。 1、做VI設計和畫冊設計的時候要註意設計的層次感,什麽信息該放在前面,什麽信息該要放在最後,這都需要事先考慮做好準備工作。此外VI和畫冊的設計中有兩個方面的設計,一是觀看,二是閱讀。同時要考慮顧客們的視覺、閱讀習慣來

@RequestMapping @ResponseBody @RequestBody 註解的用法與區別

ber attribute thrown text 返回結果 mode 需要 oca 格式 1.@RequestMapping 國際慣例先介紹什麽是@RequestMapping,@RequestMapping 是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,

C#之虛方法抽象方法的區別

C# 虛方法 抽象方法 多態 抽象類:有時我們表達一些抽象的東西,它是一種概括,不需要它成為一種實體,所以面向對象便有了抽象類。具體來講:一個員工,它屬於一個公司,但是公司只是一個名稱,我們不需要它成為一個實體,所以公司就是一個抽象類。何時必須聲明一個類為抽象類?(面試題)當這個類中包含抽象方

空指標棧,堆記憶體

/**    * 堆記憶體(heap):儲存每一個物件的屬性,使用一個物件時,一定需要一個對應堆記憶體的指向,而堆記憶體空間的開闢需要用關鍵字     *new,每一個物件在剛剛例項化後,裡面的屬性都是其對應資料型別的預設值,一塊堆記憶體可以被多個棧

js變數宣告

----淺談js變數宣告   或者確切地說應該是變數宣告以及與之相關的一些東西。   這裡只談四種宣告方式(var,function,let,const),其它的宣告方式以後有接觸再更新。 ‘var’ VS ‘let’   var貌似是最常用的,在ES6還沒出來的時候只能用v

python 深入變數引用物件

變數和物件 在《learning python》中的一個觀點:變數無型別,物件有型別 在python中,如果要使用一個變數,不需要提前宣告,只需要在用的時候,給這個變數賦值即可。這裡特別強調,只要用一個變數,就要給這個變數賦值。 所以,像這樣是不行的。 >>&

Shell程式設計-03-Shell中的特殊變數擴充套件變數

特殊變數     在Shell中的特殊變數主要分別兩種位置引數變數、狀態變數兩種。 位置引數變數     Shell中的位置引數變數主要是指$0、$1、$#等,主要用於從命令列、函式或指令碼執行等地方傳遞引數。詳細說明如下所示: $0:獲取當前執行的Shell指令碼的檔名,如指令碼中包含路徑,則

先驗分佈後驗分佈

【前言】 上文提到貝葉斯定理是先驗分佈和後驗分佈轉換的橋樑,貝葉斯學派計算引數後驗分佈的難點在於如何選擇引數的先驗分佈,本文通過二項式分佈的例子來形象的表達如何選擇先驗分佈和計算後驗分佈,並闡述了先驗分佈和後驗分佈是如何轉換的,最後對本文進行總結。     &nb

頻率學派貝葉斯學派

【寫在前面的話】 終於可以寫貝葉斯相關的文章啦,心情有點小激動,最近一段時間反覆看Bishop老師編寫的<<Pattern Recognition and Machine Learning>>前三章章節,發現貝葉斯思想真是太強大了,瞬間成為該書作者的忠實粉絲。在後續的

new/deletemalloc/free的用法與區別

  淺談new/delete和malloc/free的用法與區別 目錄 一.new和delete用法 二.malloc和free的用法 三.new和malloc的區別   正文   每個程式在執行時都會佔用一塊可用的記憶體空間,

Linux協議組成

根據自己學習Linux方面的知識,淺談下linux的協議和組成,那首先了解下計算機的組成和功能: 計算機系統由硬體(hardware)系統和軟體(software)系統兩大部分組成: 1、硬體系統由主機和外部裝置組成: 主機

深度優先廣度優先(scrapy-redis)

首先先談談深度優先和廣度優先的定義 深度優先搜尋演算法(英語:Depth-First-Search,DFS)是一種用於遍歷或搜尋樹或圖的演算法。沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。當節點v的所在邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有