Shell環境變量與特殊變量詳解

1)變量類型

1)變量可分爲倆類:環境變量(全局變量),和普通變量(局部變量),

  環境變量也稱爲全局變量,能夠在建立他們的Shell及其派生出來的任意子進程Shell中使用,環境變量又能夠分爲自定義環境變量和bash內置的環境變量,環境變量能夠在命令行中設置和建立,用戶退出命令行時這些變量值就會丟失,想要永久保存環境變量,可在用戶家目錄下的. bash_profile. bashrc(非用戶登陸模式特有,如:SSH)文件中,或在/etc/profile文件中定義,這樣每次用戶登陸時這些變量都將被初始化。bash

普通變量也可成爲局部變量,只能在建立它們的Shell函數或Shell腳本中使用,普通變量通常由開發者在開發腳本程序時建立,網絡

2)查看設置的變量

set命令輸出全部的變量,包括全局變量和局部變量app

 1  [root@king ~]# set
 2     APACHEERR=hello world  3     BASH=/bin/bash  4     BASH_ALIASES=()  5     BASH_ARGC=()  6     BASH_ARGV=()  7     BASH_CMDS=()  8     BASH_LINENO=()  9     BASH_SOURCE=() 10     BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" 
11     中間和結尾省略若干代碼

env(printenv)命令只顯示全局變量,ssh

1 [king@king~]$ env 2 HOSTNAME=king 3 SHELL=/bin/bash   #你們能夠自行查看一下哦

declare命令輸出全部的變量,函數,整數,和已經導出的變量,set -o命令顯示bashShell的全部參數配置信息函數

3)自定義環境變量

若是想設置環境變量,就要給在給變量賦值後或在設置變量時使用export命令,export命令和declare命令的格式:學習

  1. export 變量名=value
  2. 變量名=value ; export 變量名
  3. declare - x 變量名=value

小試牛刀:定義環境變量並賦值的方法:測試

  1. export NAME=qzlking
  2. declare -x NAME=qzlking
  3. NAME=qzlking ; exprot NAME
 1 [root@king script]# cat /etc/profile|grep qzl  2  export qzl='qzlking'       #<==編輯/etc/profile,而後輸出此行並保存  3 [root@king script]# source /etc/profile         #<==或./etc/profile使其生效  4 [root@king script]# echo $qzl                   #<==在變量前加$符號並打印變量值  5  qzlking  6 [root@king script]# env|grep qzl                #<==查看定義結果  7  qzl=qzlking

咱們一塊兒來看一下讓環境變量永久生效的經常使用配置文件ui

a)用戶環境變量配置spa

1 [root@king scripts]# ls /root/.bashrc 2 /root/.bashrc 3 [root@king scripts]# ls /root/.bash_profile 4 /root/.bash_profile

說明:對於用戶的環境變量設置,常見的是用戶家目錄下的.bashrc和.bash_profile。命令行

b)全局環境變量的配置

常見的全局環境變量配置文件,/etc/profile;/etc/bashrc;/etc/profile.d這三個配置文件,若是想要在登錄後初始化或者顯示加載的內容,只須要把腳本文件放在/etc/profile.d文件下便可(不須要加執行權限)。

 在Java環境中,自定義環境變量,一般放在/etc/profile全局環境變量裏哦,

1 export JAVA_HOME=/application/jdk 2 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib 3 export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin 4 export RESIN_HOME=/application/resin   

4)查看/取消環境變量

咱們一般在工做中要查看一下環境變量中都配置了什麼,須要作什麼更改,因此咱們就有了ehco或printf命令來打印查看環境變量。

  1. $HOME:用戶登陸時進入的目錄
  2. $UID:當前用戶的uid( 也就是用戶的標識,至關於人的身份證)至關於id -u
1 [king@king ~]$ echo $HOME 2 /home/king 3 [king@king ~]$ echo $UID 4 300

咱們能夠用unset來消除本地變量和環境變量

1 [king@king ~]$ echo $USER 2 nane 3 [king@king ~]$ unset $USER 4 [king@king ~]$ echo  $USER  #<這裏輸出是個空行 5 

小結:

  • 變量名必定要大寫,能夠在自身的Shell及子Shell中使用,經常使用export來定義環境變量
  • 執行enc默承認以顯示全部的環境變量名稱及對應的值
  • 輸出時用「$變量名」,取消用「unset 變量名」

2)環境變量初始化與對應文件的生效順序

1.登錄Shell讀取環境變量文件的流程

 

  用戶登陸系統後首先會加載/etc/profile全局環境變量文件,加載完後,執行/etc/profile.d目錄下的腳本文件(如:系統的字符集設置/etc/sysconfigil8n),而後在運行$HOME/.bash_profile(用戶環境變量文件),在這文件裏會找$HOME/.bashrc(用戶環境變量文件),有就執行,沒有就不執行。在$HOME/.bashrc找/etc/bashrc(全局環境變量文件)有就執行,沒有就不執行。若是但願用戶的Shell不是登錄時啓動的(如:手動敲下bash時啓動或者遠程ssh鏈接狀況),非登錄Shell只會加載$HOME/.bashrc(用戶環境變量文件),並會去找/etc/bashrc(全局環境變量文件)。即非登錄Shell想讀到設置的環境變量,須要將變量設定等寫入$HOME/.bashrc(用戶環境變量文件)或etc/bashrc(全局環境變量文件)不是$HOME/.bash_profile或/etc/profile。。。

3)定義本地變量

1)普通變量的定義,有三種寫法

  1. 變量名=value       #不加引號時,值裏有變量的會被解析後輸出。 
  2. 變量名='value'     #輸出變量內容時單引號裏是什麼就輸出什麼,無論什麼都原樣輸出。
  3. 變量名="value"    #輸出變量內容時引號裏的變量和命令通過解析後輸出。

2)命令結果做爲的變量內容來賦值

  1. 變量名=`mkdir`    #這裏是反引號,
  2. 變量名=$(mkdir)  #把命令$()括起來,來賦值。 

4)變量定義的技巧總結

  • 變量名只能爲字母,數字或者下劃線,只能以字母或下劃線開頭,要見名知意。
  • 通常變量的定義,賦值經常使用雙引號,但願原樣輸出的加單引號。
  • 但願變量的內容是命令的解析結果時,要用反引號``,或者用$()把命令括起來在賦值
  • 打印輸出或使用變量時,變量名前要接$符號。

變量定定義示例:

1 KingAge=25        #<==每一個單詞的首字母大寫的寫法 2 king_age=25       #<==單詞之間用"_"的寫法 3 kingAgeSex=25    #<==駝峯語法: 首個單詞的首字母小寫,其他單詞首字母大寫 4 kingAGE=25        #<==單詞全大寫的寫法

5)Shell特殊位置變量

Shell中存在一些特殊且重要的變量,以下

  • $0    獲取當前執行Shell腳本的文件名字,若是執行腳本時候加了路徑,那就包含腳本路徑跟腳本名字一塊兒輸出
  • $n    獲取當前執行Shell交本的第n個參數,n=1..9,n>9,後面參數變量就須要用大括號,如:${10},以空格分隔
  • $#    獲取當前執行Shell腳本接了多少個參數(總計)
  • $*    獲取當前執行Shell腳本全部傳參的參數
  • $@    獲取當前執行Shell腳本全部傳參的參數($*和$@詳解見例子)
 1 [root@ king tmp]# cat t.sh
 2 if [ $# -ne 2 ]             #若是執行腳本傳參的個數不爲2,
 3   then
 4     echo "USAGE:/bin/sh $0 arg1 arg2"    #則給用戶提示正確用法,此處的$0,打印腳本名字及路徑。
 5     exit 1                #若不知足要求,則退出腳本,返回值爲1。
 6 fi
 7 echo $1 $2                  #若參數知足要求,則打印$1和$2獲取到的傳參的字符串。
 8 [root@ king tmp]# sh t.sh            #若不加參數執行腳本,則直接給出提示。
 9 USAGE:/bin/sh t.sh arg1 arg2           #t.sh就是腳本中$0獲取的值。
10 [root@ king tmp]# sh t.sh hello world
11 hello world                        #若參數知足要求,則打印$1和$2獲取的字符串,即hello和world。

$0,$n,$#,這幾個就很少說了,由於太好理解了,下面咱們來一塊兒學習一下$*和$@的區別吧。

咱們能夠利用set 來設置位置參數Age of loss

 1 [root@king tmp]# set -- "This is" Age of loss.  #「--」表示清除全部的參數變量,從新設置後面的參數變量。
 2 [root@king tmp]#echo $#    #輸出參數的個數。
 3 3                 #共三個參數。
 4 [root@king tmp]# echo $1    #打印第一個參數值。
 5 This is
 6 [root@king tmp]# echo $2    #打印第二個參數值。
 7 Age
 8 [root@king tmp]# echo $3    #打印第三個參數值。
 9 of
10 [root@king tmp]# echo $4    #打印第四個參數值。
11 loss.
12 #測試$*和$@,注意,此時不帶雙引號:
13 [root@king tmp]# echo $*    #打印$*。
14 This is Age of loss.
15 [root@king tmp]# echo $@     #打印$@。
16 This is Age of loss.
17 [root@king tmp]# for i in $*; do echo $i; done           #使用for循環輸出$*測試。
18 This          #($*)不加雙引號,所以會輸出全部參數,而後第一個參數"This is"也拆開輸出了。
19 is
20 Age
21 of
22 loss
23 [root@king tmp]# for i in $@; do echo $i; done    #使用for循環輸出$@測試。
24 This              #($@)不加雙引號,所以會輸出全部參數,而後第一個參數"This is"也拆開輸出了。
25 is
26 Age
27 of
28 loss
29 #測試"$*"和"$@",注意,此時帶有雙引號:
30 [root@king tmp]# echo "$*"
31 This is Age of loss.
32 [root@king tmp]# echo "$@"
33 This is Age of loss.
34 [root@king tmp]# for i in "$*"; do echo $i; done
35 This is Age of loss.   #在有雙引號的狀況下"$*",參數裏引號中的內容看成一個參數輸出了!
36 [root@king tmp]# for i in "$@"; do echo $i; done
37 This is   #在有雙引號的狀況下,每一個參數均以獨立的內容輸出,且有雙引號算一個參數。
38 Age
39 of
40 loss
41 #這才真正符合咱們傳入的參數需求,set -- "This is" Age of loss.

6)Shell特殊狀態變量

Shell特殊狀態變量

  • $?     獲取執行上一個指令的執行狀態返回值(0成功,非0爲失敗)
  • $$      獲取當前執行Shell腳本的進程號(PID)
  • $!      獲取上一個在後臺工做的進程的進程號(PID)
  • $_      獲取在此以前執行的命令或腳本的最後一個參數

$?特殊變量,根據返回值來判斷備份成功於否,例子

1 [root@king tmp]# cd /etc/
2 [root@king  etc]# tar zcf /opt/services.tar.gz ./services     #打包備份
3 [root@king  etc]#  echo  $?   #檢查備份後的,返回0表示打包成功,
4 0

咱們能夠查看一下NFS網絡文件共享系統/etc/init.d/rpcbind腳本中的50-73行吧,學習一下$?使用,

 1 [root@king scripts]# sed -n '63,73p' /etc/init.d/rpcbind        #sed  -n 打印文件指定行、
 2 stop() {
 3         echo -n $"Stopping $prog: "
 4      killproc $prog                      #這是中止rpcbind的命令。
 5         RETVAL=$?                     #將上述命令的返回值「$? 」賦值給RETVAL變量,用於後面的判斷。
 6         echo
 7         [ $RETVAL -eq 0 ]&&{        #這裏就是判斷,若是返回值爲0,則執行下面的指令。
 8                 rm -f /var/lock/subsys/$prog
 9                 rm -f /var/run/rpcbind*
10         }
11         return $RETVAL       #若是返回值不等於0,則跳過判斷,直接做爲返回值傳給執行stop函數的腳本。
12 }

$?返回值的用法總結:

  1. 判斷命令,腳本或者函數等程序是否執行成功
  2. 若在腳本中調用執行「exit 數字」,則會返回這個數字給「$?」變量
  3. 若是是在函數裏,則經過「return 數字」,把這個數字以函數返回值的形式傳給「$?」

7)Shell特殊擴展變量

Shell特殊位置變量

咱們能夠man bash 命令,而後搜索"Parameter Expansion"來查找相關的內容幫助

  • ${parameter:-word}       若是parameter的變量值爲空或沒賦值,則返回word字符串並代替變量的值(變量沒定義,返回備用的值,防止變量爲空或沒定義報錯)
  • ${parameter:=word}      若是parameter的變量值爲空或沒賦值,。。。同上,(變量沒定義爲防止出錯,找的備胎變量)
  • ${parameter:?word}      若是parameter的變量值爲空或者沒賦值,word字符串就做爲標準錯誤輸出,不然出書變量的值(捕捉因爲變量未定義致使的錯誤,並退出)
  • ${parameter:+word}      若果parameter的變量值爲空或者未賦值,則什麼都不作,不然word字符串將代替變量的值。

${parameter:-word}用法距離:沒有賦值的狀況

1 [root@king tmp]# echo $test      #變量未設置,因此輸出時爲空。
2 [root@king tmp]# result=${test:-UNSET}       #<==若test沒值,則返回UNSET。
3 [root@king tmp]# echo $result    #打印result變量,返回UNSET,由於test沒有賦值。
4 UNSET
5 [root@king tmp]# echo ${test}    #注意,此時打印test變量仍是爲空。
結論:對於${test:-UNSET},當test變量沒值時,就返回變量結尾設置的UNSET字符串。
賦值的狀況
1 [root@king tmp]# test=hello  #賦值hello字符串。
2 [root@king tmp]# echo $test
3 hello
4 [root@king tmp]# result=${test:-UNSET}              
5 [root@king tmp]# echo $result  #由於test已賦值,所以,打印result就輸出了test的值hello,而不是原來的UNSET。
6 hello
7 [root@king tmp]# result=${test-UNSET}               #定義時忽略了冒號。
8 [root@king tmp]# echo $result
9 hello                                               #打印結果和帶冒號時沒有變化。

${parameter:=word}和${parameter:-word}差很少,理解都是同樣的,變量爲賦值就把備胎給變量。。。

${parameter:?word}變量爲賦值或空,就將該字符串(word)做爲標準錯誤輸出。

 1 [root@king tmp]# echo ${key:? not defined}   #key變量沒有定義,所以,把「not defined」做爲標準錯誤輸出。
 2 -bash: key: not defined       #錯誤提示,只不過是事先定義好的錯誤輸出。
 3 [root@king tmp]# echo ${key? not defined}     #去掉冒號定義,並輸出,結果一致。
 4 -bash: key: not defined
 5 [root@king tmp]# key=5 #<==給變量賦值1。
 6 [root@king tmp]# echo ${key:? not defined}    #由於key有值了,因此,打印key的值。
 7 5
 8 [root@king tmp]# echo ${key? not defined}     #去掉冒號定義,並輸出,結果一致。
 9 5
10 [root@king tmp]# unset key     #取消key的定義。
11 [root@king tmp]# echo ${key:? not defined}
12 -bash: key: not defined           #又打印錯誤提示了。

${parameter:+word}變量爲空或沒賦值,什麼都不作,不然用word字符串替換變量的值

1 [root@king tmp]# key=${value:+word}      #value變量未定義。
2 [root@king tmp]# echo $key        #由於value變量未定義,因此打印key變量爲空。
3 [root@king tmp]# value=25           #value變量賦值爲25。
4 [root@king tmp]# key=${value:+word} #注意,這裏必定要從新定義key。
5 [root@king tmp]# echo $key
6  word                           #由於value變量有值,因此打印key變量輸出爲「:+ 」後面的內容。
相關文章
相關標籤/搜索