<b>3.2 環境變量</b>
<b></b>
環境變量一般是指用export内置指令導出的變量,用于定義shell的運作環境,保證shell指令的正确執行。shell通過環境變量來确定登入使用者名、指令路徑、終端類型、登入目錄等,所有的環境變量都是系統全局變量,可用于所有子程序中,這包括編輯器、shell腳本和各類應用。
環境變量可以在指令行中設定和建立,但使用者退出指令行時這些變量值就會丢失,是以,如果希望永久儲存環境變量,可在使用者家目錄下的.bash_prof?ile或.bashrc(非使用者登入模式特有,例如遠端ssh)檔案中,或者全局配置/etc/bashrc(非使用者登入模式特有,例如遠端ssh)或/etc/prof?ile檔案中定義。在将環境變量放入上述的檔案中後,每次使用者登入時這些變量都将被初始化。
按照系統規範,所有環境變量的名字均采用大寫形式。在将環境變量應用于使用者程序程式之前,都應該用export指令導出定義,例如:正确的環境變量定義方法為export oldgirl=1。
有一些環境變量,比如home、path、shell、uid、user等,在使用者登入之前就已經被/bin/login程式設定好了。通常環境變量被定義并儲存在使用者家目錄下的.bash_prof?ile檔案或全局的配置檔案/etc/prof?ile中,具體的環境變量說明參見表3-1。
表3-1 部分bash環境變量展示(執行env指令後獲得)
變量名 含 義
_= 上一條指令的最後一個參數
bash=/bin/bash 調用bash執行個體時使用的全路徑名
bash_versinfo=([0]="3"[1]="2"[2]="25" [3]="1"[4]="release"[5]="x86_64-redhat-linux-gnu") 使用2.0以上版本時,展開為版本資訊
bash_version='3.2.25(1)-release' 目前bash執行個體的版本号
colors=/etc/dir_colors 顔色變量
columns=132 設定該變量,就給shell編輯模式和選擇的指令定義了編輯視窗的寬度
dirstack=() 代表目錄棧的目前内容
euid=0 在shell啟動時被初始化的目前使用者的有效id
groups=() 目前使用者所屬的組
histfile=/root/.bash_history 曆史記錄檔案的全路徑
histfilesize=50 曆史檔案能包含的最大行數
histsize=50 記錄在指令行曆史檔案中的指令行數
home=/root 目前使用者家目錄
hostname=oldboy 目前主機名稱
hosttype=x86_64 目前作業系統類型
ifs=$'\t\n' 内部字段分隔符,一般是空格符、制表符和換行符,用于劃分由指令替換、循環結構中的表和所讀取的輸入産生的詞的字段
inputrc=/etc/inputrc readline啟動檔案的檔案名,取代預設的~/.inputrc
java_home=/application/jdk1.6.0_10 java home環境變量
lang=zh_cn.utf-8 字元集
logname=root 登入使用者名稱
machtype=x86_64-redhat-linux-gnu 包含一個描述正在運作bash的系統串
mailcheck=60 這個參數定義shell将隔多長時間(以秒為機關)檢查一次由參數mailpath或mailfile指定的檔案,看看是否有郵件到達。預設值為600s
mail=/var/spool/mail/root 郵件全路徑
oldpwd=/root 前一個目前工作目錄
optind=1 下一個由getopts内置指令處理的參數的序号
ostype=linux-gnu 自動設定成一個串,該串描述正在運作bash的作業系統,預設值由系統來決定
path=/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:
/usr/kerberos/bin
:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/bin:
/server/script/shangxian:/root/bin 全局path路徑,指令搜尋路徑。一個由冒号分隔的目錄清單,shell用它來搜尋指令。預設路徑由系統來決定,并且由安裝bash的管理者來設定
pipestatus=([0]="0"[1]="0") 一個數組,包含一列最近在管道執行的前台作業的程序退出的狀态值
ppid=1112 父程序的程序id
ps1='[\u@\h \w]\$ ' 主提示符串,預設值是$
ps2='>' 次提示符串,預設值是>
ps4=`+` 當開啟追蹤時使用的是調試提示符串,預設值是+,追蹤可用set –x開啟
pwd=/home 目前使用者家目錄
resin_home=/application/resin-3.1.6 這是通過export人為設定的環境變量,java環境會用
shell=/bin/bash 登入shell類型
shellopts=braceexpand:emacs:hashall:
histexpand:history:interactive-comments:monitor 包含一列開啟的shell選項
shlvl=1 每啟動一個bash執行個體就将其加1
term=vt100 終端設定
tmout=3600 退出前等待逾時的秒數
uid=0 目前使用者的uid,在shell啟動時初始化
user=root 目前使用者的使用者名,在shell啟動時初始化
在檢視設定的變量時,有3個指令可以顯示變量的值:set、env和declare(替代早期的typeset)。set指令輸出所有的變量,包括全局變量和局部變量;env指令隻顯示全局變量;declare指令輸出所有的變量、函數、整數和已經導出的變量。set -o指令顯示bash shell的所有參數配置資訊。
範例3-1:set、env和declare輸出。
[root@oldboy ~]# env|tail
shlvl=1
home=/root
logname=root
cvs_rsh=ssh
moduleshome=/usr/share/modules
lessopen=||/usr/bin/lesspipe.sh %s
g_broken_filenames=1
bash_func_module()=() { eval `/usr/bin/modulecmd bash $*`
}
_=/bin/env
[root@oldboy ~]# declare|tail
_module_not_yet_loaded ()
{
comm -23 <(_module_avail|sort) <(tr : '\n' <<<${loadedmodules}|sort)
module ()
eval `/usr/bin/modulecmd bash $*`
[root@oldboy ~]# set|tail
[root@oldboy ~]# set -o|head
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
3.2.1 自定義環境變量
1.?設定環境變量
如果想要設定環境變量,就要在給變量指派之後或在設定變量時使用export指令,具體設定見下文的示例。其實,除了export指令,帶-x選項的declare内置指令也可以完成同樣的功能(注意:此處不要在變量名前面加$)。
export指令和declare指令的格式如下:
①export 變量名=value
②變量名=value ; export 變量名
③declare –x 變量名=value
提示: 以上為設定環境變量的3種方法。
範例3-2:定義環境變量并指派的方法。
export name=oldboy
declare –x name=oldboy
name=oldboy ;export name
以下是自定義全局環境變量的示例:
[root@oldboy script]# cat /etc/profile|grep old
export oldboy='oldboy' #<==編輯/etc/profile,然後輸出此行并儲存
[root@oldboy script]# source /etc/profile #<==或. /etc/profile使其生效
[root@oldboy script]# echo $oldboy #<==在變量前加$符号并列印變量值
oldboy
[root@oldboy script]# env|grep oldboy #<==檢視定義結果
oldboy=oldboy
下面來看看讓環境變量永久生效的常用設定檔案。
(1)使用者的環境變量配置
配置如下:
[root@oldboy scripts]# ls /root/.bashrc #<==推薦在此檔案中優先設定
/root/.bashrc
[root@oldboy scripts]# ls /root/.bash_profile
/root/.bash_profile
提示: 對于使用者的環境變量設定,比較常見的是使用者家目錄下的.bashrc和.bash_profile。
(2)全局環境變量的配置
常見的全局環境變量的配置檔案如下:
/etc/profile
/etc/bashrc #<==推薦在此檔案中優先設定
/etc/profile.d/
若要在登入後初始化或顯示加載内容,則把腳本檔案放在/etc/prof?ile.d/下即可(無須加執行權限)。
2.?設定登入提示的兩種方式
第一種是在/etc/motd裡增加提示的字元串,如下:
[root@oldboy ~]# cat /etc/motd #<==檔案裡僅為字元串内容
welcome to oldboy linux shell training.
登入後顯示内容如下:
last login : fri nov 7 15 :36 :56 2016 from 10.0.0.100
第二種是在/etc/prof?ile.d/下面增加如下腳本。
[root@oldboy ~]# cat /etc/profile.d/oldboy.sh #<==這裡是腳本的内容
echo " here is oldboy training "
登入後顯示的内容如下:
here is oldboy training
以下是在生産場景下(在java環境中),自定義環境變量的示例。
export java_home=/application/jdk
export classpath=$classpath:$java_home/lib:$java_home/jre/lib
export path=$java_home/bin:$java_home/jre/bin:$path:$home/bin
export resin_home=/application/resin
提示: 上述的環境變量設定通常放在/etc/profile全局環境變量裡。
如果是寫java的腳本,那麼最好是把上述java環境配置放入腳本内重新定義,特别是作為定時任務執行的腳本。
3.2.2 顯示與取消環境變量
1.?通過echo或printf指令列印環境變量
下面我們先來看看常見的系統環境變量。
$home:使用者登入時進入的目錄。
$uid:目前使用者的uid(使用者辨別),相當于id?-u。
$pwd:目前工作目錄的絕對路徑名。
$shell:目前shell。
$user:目前使用者。
......
範例3-3:通過echo和printf指令列印環境變量。
[oldboy@oldboy ~]$ echo $home
/home/oldboy
[oldboy@oldboy ~]$ echo $uid
504
[oldboy@oldboy ~]$ echo $pwd
[oldboy@oldboy ~]$ echo $shell
/bin/bash
[oldboy@oldboy ~]$ echo $user
[root@oldboy ~]# printf "$home\n"
#<==printf是一個更複雜的格式化列印内容的工具,一般不需要
/root
提示: 在寫shell腳本時可以直接使用系統預設的環境變量,一般情況下是不需要重新定義的,在使用定時任務等執行shell腳本時建議在腳本中重新定義。
2.?用env或set顯示預設的環境變量
用env(printenv)顯示預設環境變量的示例如下:
[oldboy@oldboy ~]$ env
hostname=oldboy
shell=/bin/bash
histsize=1000
lc_all=c
mail=/var/spool/mail/oldboy
path=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/oldboy/bin
inputrc=/etc/inputrc
pwd=/home/oldboy
lang=zh_cn.gb18030
home=/home/oldboy
logname=oldboy
中間和結尾省略若幹代碼
用set也可以顯示環境變量(包括局部變量),如下:
[root@oldboy ~]# set
apacheerr=hello
bash=/bin/bash
bash_aliases=()
bash_argc=()
bash_argv=()
bash_cmds=()
bash_lineno=()
bash_source=()
bash_versinfo=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
bash_version='4.1.2(1)-release'
colors=/etc/dir_colors
columns=103
在3.2.1節還提到了一個相關的指令declare,大家還記得嗎?
3.?用unset消除本地變量和環境變量
用unset消除本地變量和環境變量的示例如下:
[oldboy@oldboy ~]$ unset user
#<==此處為輸出的空行
可以看到變量的内容顯示為空。
環境變量的知識小結:
變量名通常要大寫。
變量可以在自身的shell及子shell中使用。
常用export來定義環境變量。
執行env預設可以顯示所有的環境變量名稱及對應的值。
輸出時用“$變量名”,取消時用“unset變量名”。
書寫crond定時任務時要注意,腳本要用到的環境變量最好先在所執行的shell腳本中重新定義。
如果希望環境變量永久生效,則可以将其放在使用者環境變量檔案或全局環境變量檔案裡。
3.2.3 環境變量初始化與對應檔案的生效順序
在登入linux系統并啟動一個bash shell時,預設情況下bash會在若幹個檔案中查找環境變量的設定。這些檔案可統稱為系統環境檔案。bash檢查的環境變量檔案的情況取決于系統運作shell的方式。系統運作shell的方式一般有3種:
1) 通過系統使用者登入後預設運作的shell。
2) 非登入互動式運作shell。
3) 執行腳本運作非互動式shell。
當使用者登入linux系統時,shell會作為登入shell啟動。此時的登入shell加載環境變量的順序如圖3-1所示。
使用者登入系統後首先會加載/etc/profile全局環境變量檔案,這是linux系統上預設的shell主環境變量檔案。系統上每個使用者登入都會加載這個檔案。
當加載完/etc/profile檔案後,才會執行/etc/profile.d目錄下的腳本檔案,這個目錄下的腳本檔案有很多,例如:系統的字元集設定(/etc/sysconfig/i18n)等,在後文開發跳闆機案例裡,我們也把腳本的起始加載放到這個目錄下,以便使用者登入後即刻運作腳本。
之後開始運作$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。