天天看點

跟老男孩學Linux運維:Shell程式設計實戰3.2 環境變量

<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='&gt;' 次提示符串,預設值是&gt;

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 &lt;(_module_avail|sort) &lt;(tr : '\n' &lt;&lt;&lt;${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' #&lt;==編輯/etc/profile,然後輸出此行并儲存

[root@oldboy script]# source /etc/profile #&lt;==或. /etc/profile使其生效

[root@oldboy script]# echo $oldboy #&lt;==在變量前加$符号并列印變量值

oldboy

[root@oldboy script]# env|grep oldboy #&lt;==檢視定義結果

oldboy=oldboy

下面來看看讓環境變量永久生效的常用設定檔案。

(1)使用者的環境變量配置

配置如下:

[root@oldboy scripts]# ls /root/.bashrc #&lt;==推薦在此檔案中優先設定

/root/.bashrc

[root@oldboy scripts]# ls /root/.bash_profile

/root/.bash_profile

提示: 對于使用者的環境變量設定,比較常見的是使用者家目錄下的.bashrc和.bash_profile。

(2)全局環境變量的配置

常見的全局環境變量的配置檔案如下:

/etc/profile

/etc/bashrc #&lt;==推薦在此檔案中優先設定

/etc/profile.d/

若要在登入後初始化或顯示加載内容,則把腳本檔案放在/etc/prof?ile.d/下即可(無須加執行權限)。

2.?設定登入提示的兩種方式

第一種是在/etc/motd裡增加提示的字元串,如下:

[root@oldboy ~]# cat /etc/motd #&lt;==檔案裡僅為字元串内容

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 #&lt;==這裡是腳本的内容

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"

#&lt;==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

                                #&lt;==此處為輸出的空行

可以看到變量的内容顯示為空。

環境變量的知識小結:

變量名通常要大寫。

變量可以在自身的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。