Shell程式設計-02-Shell變數

Surpassme發表於2018-11-07

什麼是Shell變數

    在初等數學數學方程式中,我們會經常碰到類似於這樣的方程式:y=x+1 ,等號左右兩邊的xy稱之為未知數。在程式設計裡面它們他們則代表變數名與變數值。
4-1 變數含義_c2i.jpg

    通過該示例,我們可以得出一個結論:簡單來說,變數是程式設計中最基本的儲存單位,它會暫時儲存使用者放進去的資料,而儲存的資料位於記憶體空間中,通過正確呼叫記憶體空間中變數名字即可以取出與之對應的資料。在Shell中定義變數和取值如下所示:

4-2 變數示例.jpg

變數注意事項

1、定義變數的方法,先定義變數名,緊跟賦值操作符=,最後是變數對應的值,中間不能存在空格,否則會出現報錯,這一點是跟其他語言比較大的區別,如下所示:

4-3 變數賦值.jpg

2、列印變數值,需要在變數名前加$${},如下所示:

   echo $y
   echo ${y}

3、變數名只能為字母、數字或下劃線且只能以字母或下劃線開頭(這一點跟大多數語言一樣,至於為什麼請問度娘)

4、變數名需要遵循一定的規範,並且要一見名便知其意。

常見的命令規範有三種:

  • 匈牙利命名法
    該命令方法是在每個變數名前新增表示資料型別的字元
  • 駝峰命名法
    混合使用大小寫字母來對變數進行命名。而且是首字母小寫,後續單詞第一個字母大寫,如userName
  • 帕斯卡命名法
    與駝峰法很很像,每個單詞第一個字母均大寫,如UserName

5、環境變數需要全部採用大寫形式書寫

6、在其他強類開語言中(如Java/C#)對資料型別都有其嚴格的定義,如整型int、字元char、字串string、小數float/double/decimal等等。而在Shell中,預設是不區分變數型別的。如果需要顯式定義變數型別,則可以使用declare定義。

7、如果要在crond做定時任務時需要在Shell指令碼中使用環境變數需要先在執行指令碼中重新定義

變數型別

    變數可分為兩類:環境變數(全域性變數)普通變數(區域性變數),而環境變數又可以分為bash內建環境變數使用者自定義環境變數。詳細可參考下圖所示:

4-4 變數型別_c2i.jpg

環境變數(全域性變數):可以在建立它們的Shell和其任意子Shell程式中使用
普通變數(區域性變數):僅能在建立它們的Shell函式和指令碼中使用

內建環境變數

    環境變數一般是指使用export內建命令匯出的變數,用於定義Shell的執行環境、保證Shell命令的正確執行。Shell通過環境變數來確定登入使用者名稱、命令路徑、終端型別、登入目錄等,所有的環境變數都是系統全域性變數,可用於所有子程式中。
    環境變數可以在命令列中設定和建立,但在使用者退出命令列時這些變數值就會丟失。如果希望永久儲存環境變數,可以在使用者目錄下的.bashrc.bash_profile檔案中或全域性變數配置/etc/profile檔案中定義。在將環境變數放入上述檔案後,每次使用者登入時這些變數都將被初始化。

  • 1、按照系統規範,所有環境變數的名字必須採用大寫形式
  • 2、在將環境變數應用於使用者程式程式之前,都應該用export命令匯出定義。如export JAVA_HOME
  • 3、有部分環境變數,如HOME、PATH、SHELL、UID、USER等,的使用者登入之前就已經被/bin/login程式設定好了。通常環境變數被定義並儲存在使用者目錄下的.bash_profile或/etc/profile中。
  • 4、在檢視設定的變數時,有3個命令可顯示變數的值:set、env、declare
set:輸出所有的變數,包括全域性變數和區域性變數
env:只顯示全域性變數
declare:輸出所有的變數、函式、整數和已經匯出的變數
set -o:顯示bash Shell的所有引數配置資訊

env檢視系統環境變數:

4-5 系統環境變數env.jpg

declare檢視所有變數、函式、整數等

4-6 系統環境變數declare_c2i.jpg

set輸出所有變數

4-7 系統環境變數set_c2i.jpg

set -o輸出bash引數配置

4-8 系統環境變數set-o.jpg

自定義環境變數

設定環境變數

    如果想要設定環境變數,就要在給變數賦值前之後或在設定變數時使用export命令,除export命令,使用declare -x命令也可以實現同樣的功能。示例如下:

export JAVA_HOME=/usr/local/java
或
JAVA_HOME=/usr/local/java;export JAVA_HOME
或
declare -x JAVA_HOME=/usr/local/java

以上為設定自定義環境變數的3種方法,而在此處不要在變數名前新增$

  • 自定義環境變數示例

4-9 自定義環境變數_c2i.jpg

  接下來我們來看看讓環境變數永久生效的常用設定檔案

  • 1、使用者的環境變數配置

4-10 使用者環境變數配置_c2i.jpg

對於使用者環境變數的設定,比較常見的是使用者目錄下的.bashrc和.bash_profile。推薦在~/.bash_profile中進行設定。

  • 2、全域性變數配置
    常見的全域性環境變數的配置檔案有/etc/profile/etc/bashrc/etc/profile.d

若要登入後初始化或顯示載入內容,則把指令碼檔案放在/etc/profile.d下即可,無須新增執行許可權。

示例一:設定登入提示

4-12 登入提示示例_c2i.jpg

以上任意一種方法均可,上面是兩種方法合併處理進行演示。實際操作只需要在一個檔案中操作即可。

示例二:在Linux中設定Java環境變數

export JAVA_HOME=/usr/local/java/jdk1.7.0_09
export JRE_HOME=/usr/local/java/jdk1.7.0_09/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
顯示環境變數
  • 通過echo和printf顯示環境變數

  首先我們來顯示一些常見的變數

4-13 顯示常見系統變數.jpg

從上面可以看出顯示環境變數可以使用 echoprintf 。其中printf是一種比較複雜的格式化列印工具。如果感興趣可以檢視相應的資料。

  • 通過env、set和declare顯示預設的環境變數

  可檢視前面所講內容

取消環境變數

    如果定義了環境變數,不想使用,是否可以消除環境變數定義了?在這裡我們可以使用 unset 命令。

[root@localhost ~]# echo $USER
root
[root@localhost ~]# unset USER # 清除變數,注意變數前面沒有 $
[root@localhost ~]# echo $USER
                               # 輸出為空白
普通變數
定義本地變數

    本地變數僅在使用者當前Shell中有效,如果在Shell中啟動另一個程式或退出,則變數無法進行傳遞。

  • 變數的定義及賦值如下所示:

var=value # 定義變數並進行賦值,此時沒有引號
var=`value` # 定義變數並進行賦值,此時有單引號
var=”value” # 定義變數並進行賦值,此時有雙引號
var=`value` # 定義變數並進行賦值,此時有反引號

以上變數賦值的區別如下所示:

  • 無引號:一般常用於連續的字串、數字、路徑等進行賦值。但如果變數中含有空格,則會導致賦值不完整,無法輸出完整的變數值
  • 單引號:所見即所得,即輸出時會將單引號中的所有內容原樣輸出,不做任何轉義和解釋,因此稱之為強引用
  • 雙引號:輸出引號中間的全部內容,如果引號中含有變數、特殊轉義字元、命令(需要使用反引號)等會先把變數、轉義字元、命令進行解析再輸出內容,因此稱之為弱引用
  • 反引號:常用於引用命令,即反引號中的內容會被當作命令進行解析輸出,相當於$()

以上四種賦值方法,數值內容進行賦值可以不加引號,其他若沒有特殊要求的情況,建議進行賦值均採用雙引號

定義本地變數輸出
方法一 關係 方法二
$a 等效於 ${a}
`pwd` 等效於 $(pwd)

以上兩種輸出變數值建議採取第二種方法,原因如下所示:

  • 如以使用者名稱+rc資料夾,定義變數$usernamerc,如這樣寫會導致變數為usernamerc,如果寫為${username}rc,則可以很明顯的看出變數為username
  • “,反引號容易與單引號引起混淆
定義本地變數示例
[root@localhost Test]# a=718
[root@localhost Test]# b=`718`
[root@localhost Test]# c="718"
[root@localhost Test]# d=`date +%F`
[root@localhost Test]# echo $a
718
[root@localhost Test]# echo $b
718
[root@localhost Test]# echo $c
718
[root@localhost Test]# echo ${c}
718
[root@localhost Test]# echo $d
2018-11-02
[root@localhost Test]# echo $(date +%F)
2018-11-02
[root@localhost Test]# a=823-$a
[root@localhost Test]# b=`823-$a`
[root@localhost Test]# c="823-$a"
[root@localhost Test]# echo $a
823-718
[root@localhost Test]# echo $b
823-$a
[root@localhost Test]# echo $c
823-823-718
[root@localhost Test]# echo ${c}
823-823-718
[root@localhost Test]# path=`pwd`
[root@localhost Test]# echo $path
/root/Test

環境變數初始化及其對應檔案的生效順序

    在登入Linux系統後,會預設啟動一個Shell,此時Shell會在各個配置檔案中查詢並使用對應的環境變數設定。而Shell所使用的環境變數取決於Shell的執行方式,通常分為以下三種:

  • 通過系統使用者登入後預設執行的Shell
  • 非登入互動式執行的Shell
  • 執行指令碼執行的非互動式Shell

    當使用者是通過登入Linux系統,此時Shell會作為登入Shell啟動,此時載入環境變數的順序如下所示:

4-14 環境變數初始化順序.jpg

詳細解釋如下所示:
1、使用者登入系統後會首先載入/etc/profile全域性變數檔案。

/etc/profile是Linux預設的Shell主環境變數檔案,系統上每個使用者登入都會載入該檔案。

2、當載入完/etc/profile檔案後,會執行載入/etc/profile.d目錄中的指令碼檔案。

/etc/profile.d目錄中有很多指令碼檔案,如果需要自定義登入即執行指令碼,可以將自己的指令碼放置到該目錄中。

3、前面載入完成後,開始載入~/.bash_profile(使用者環境檔案),而該檔案又會分別載入~/.bashrc和/etc/bashrc檔案。如果這些檔案存在,則執行,如沒有,則不執行。

如果使用者的Shell不是登入啟動時(如SSH遠端連線),此時這種非登入Shell只會載入$HOME/.bashrc,不會去查詢/etc/bashrc,如果需要載入這些配置,則需要將變數設定等寫入$HOME/.bashrc或者/etc/bashrc中。而不是$HOME/.bash_profile或者/etc/profile。

本文同步在微信訂閱號上釋出,如各位小夥伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼新增關注:
MyQRCode.jpg

相關文章