bash shell用一個叫做環境變量( environment variable)的特性來存儲有關shell會話和工做環境的信息(這也是它們被稱做環境變量的緣由)。這項特性容許你在內存中存儲數據,以便程序或shell中運行的腳本可以輕鬆訪問到它們。這也是存儲持久數據的一種簡便方法。java
在bash shell中,環境變量分爲兩類:正則表達式
全局環境變量對於shell會話和全部生成的子shell都是可見的。局部變量則只對建立它們的shell可見。這讓全局環境變量對那些所建立的子shell須要獲取父shell信息的程序來講很是有用。
Linux系統在你開始bash會話時就設置了一些全局環境變量。系統環境變量基本上都是使用全大寫字母,以區別於普通用戶的環境變量。redis
$ printenv HOSTNAME=server01.class.edu SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash HISTSIZE=1000 [...] HOME=/home/Christine LOGNAME=Christine [...] G_BROKEN_FILENAMES=1 _=/usr/bin/printenv
只能使用printenv命令,不要用env命令。shell
$ printenv HOME /home/Christine $ $ env HOME env: HOME: No such file or directory $
也可使用echo顯示變量的值。在這種狀況下引用某個環境變量的時候,必須在變量前面加上一個美圓符( $)。 數組
$ echo $HOME /home/Christine $
顧名思義,局部環境變量只能在定義它們的進程中可見。儘管它們是局部的,可是和全局環境變量同樣重要。事實上, Linux系統也默認定義了標準的局部環境變量。不過你也能夠定義本身的局部變量,如你所想,這些變量被稱爲用戶定義局部變量。
查看局部環境變量的列表有點複雜。遺憾的是,在Linux系統並無一個只顯示局部環境變量的命令。 set命令會顯示爲某個特定進程設置的全部環境變量,包括局部變量、全局變量
以及用戶定義變量。 bash
$ set BASH=/bin/bash [...] BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=() [...] colors=/etc/DIR_COLORS my_variable='Hello World' [...] $
能夠在bash shell中直接設置本身的變量。本節將介紹怎樣在交互式shell或shell腳本程序中建立本身的變量並引用它們。編輯器
一旦啓動了bash shell(或者執行一個shell腳本),就能建立在這個shell進程內可見的局部變量了。能夠經過等號給環境變量賦值,值能夠是數值或字符串。函數
[root@instance-3lm099to ~]# my_wife=hanmeimei [root@instance-3lm099to ~]# echo $my_wife hanmeimei [root@instance-3lm099to ~]# my_money=1000000 [root@instance-3lm099to ~]# echo $my_money 1000000
若是要給變量賦一個含有空格的字符串值,必須用單引號來界定字符串的首和尾。oop
[root@instance-3lm099to ~]# my_motto='Books are the ladder of human progress' [root@instance-3lm099to ~]# echo $my_motto Books are the ladder of human progress
若是是你本身建立的局部變量或是shell腳本,請使用小寫字母。系統環境變量都是大寫字母。 變量名區分大小寫。 請你們最好遵照這個規則,不然會帶來災難。this
記住,變量名、等號和值之間沒有空格,這一點很是重要。若是在賦值表達式中加上了空格,bash shell就會把值當成一個單獨的命令:
[root@instance-3lm099to ~]# my_wife = hanmeimei
-bash: my_wife: command not found
設置了局部環境變量後,就能在shell進程的任何地方使用它了。可是,若是生成了另一個shell,它在子shell中就不可用。
[root@instance-3lm099to ~]# my_job=teacher [root@instance-3lm099to ~]# bash [root@instance-3lm099to ~]# echo $my_job [root@instance-3lm099to ~]# exit exit [root@instance-3lm099to ~]# echo $my_job teacher
相似地,若是你在子進程中設置了一個局部變量,那麼一旦你退出了子進程,那個局部環境變量就不可用。
[root@instance-3lm099to ~]# bash [root@instance-3lm099to ~]# my_name='zhao kuang ying' [root@instance-3lm099to ~]# echo $my_name zhao kuang ying [root@instance-3lm099to ~]# exit exit [root@instance-3lm099to ~]# echo $my_name
能夠經過將局部的用戶定義變量變成全局變量來改變這種狀況。
在設定全局環境變量的進程所建立的子進程中,該變量都是可見的。建立全局環境變量的方法是先建立一個局部環境變量,而後再把它導出到全局環境中。
這個過程經過export命令來完成,變量名前面不須要加$。
[root@instance-3lm099to ~]# my_age=33 [root@instance-3lm099to ~]# export my_age [root@instance-3lm099to ~]# echo $my_age 33 [root@instance-3lm099to ~]# bash [root@instance-3lm099to ~]# echo $my_age 33 [root@instance-3lm099to ~]# exit exit [root@instance-3lm099to ~]# echo $my_age 33
修改子shell中全局環境變量並不會影響到父shell中該變量的值。
[root@instance-3lm099to ~]# my_book='this is right' [root@instance-3lm099to ~]# export my_book [root@instance-3lm099to ~]# echo $my_book this is right [root@instance-3lm099to ~]# bash [root@instance-3lm099to ~]# echo $my_book this is right [root@instance-3lm099to ~]# my_book='《this is right》' [root@instance-3lm099to ~]# echo $my_book 《this is right》 [root@instance-3lm099to ~]# exit exit [root@instance-3lm099to ~]# echo $my_book this is right
即便使用export命令,子shell也沒法改變父shell中全局環境變量的值。
刪除用unset命令,記住不要使用$。
[root@instance-3lm099to ~]# my_name=YangJie [root@instance-3lm099to ~]# echo $my_name YangJie [root@instance-3lm099to ~]# unset my_name [root@instance-3lm099to ~]# echo $my_name
和修改變量同樣,在子shell中刪除全局變量後,你沒法將效果反映到父shell中。
ps:在涉及環境變量名時,何時該使用,何時不應使用,實在讓人摸不着頭腦。記住一點就好了:若是要用到變量,使用;若是要操做變量,不使用。這條規則的一個例外就是使用顯示某個變量的值。
默認狀況下, bash shell會用一些特定的環境變量來定義系統環境。這些變量在你的Linux系統上都已經設置好了,只管放心使用。 bash shell源自當初的Unix Bourne shell,所以也保留了Unix Bourne shell裏定義的那些環境變量。
CDPATH 冒號分隔的目錄列表,做爲cd命令的搜索路徑
HOME 當前用戶的主目錄
IFS shell 用來將文本字符串分割成字段的一系列字符
MAIL 當前用戶收件箱的文件名( bash shell會檢查這個文件,看看有沒有新郵件)
MAILPATH 冒號分隔的當前用戶收件箱的文件名列表( bash shell會檢查列表中的每一個文件,看看有沒有新郵件)
OPTARG getopts 命令處理的最後一個選項參數值
OPTIND getopts 命令處理的最後一個選項參數的索引號
PATH shell 查找命令的目錄列表,由冒號分隔
PS1 shell 命令行界面的主提示符
PS2 shell 命令行界面的次提示符
BASH 當前shell實例的全路徑名
BASH_ALIASES 含有當前已設置別名的關聯數組
BASH_ARGC 含有傳入子函數或shell腳本的參數總數的數組變量
BASH_ARCV 含有傳入子函數或shell腳本的參數的數組變量
BASH_CMDS 關聯數組,包含shell執行過的命令的所在位置
BASH_COMMAND shell正在執行的命令或立刻就執行的命令
BASH_ENV 設置了的話,每一個bash腳本會在運行前先嚐試運行該變量定義的啓動文件
BASH_EXECUTION_STRING 使用bash -c選項傳遞過來的命令
BASH_LINENO 含有當前執行的shell函數的源代碼行號的數組變量
BASH_REMATCH 只讀數組,在使用正則表達式的比較運算符=~進行確定匹配( positive match)時,包含了匹配到的模式和子模式
BASH_SOURCE 含有當前正在執行的shell函數所在源文件名的數組變量
BASH_SUBSHELL 當前子shell環境的嵌套級別(初始值是0)
BASH_VERSINFO 含有當前運行的bash shell的主版本號和次版本號的數組變量
BASH_VERSION 當前運行的bash shell的版本號
BASH_XTRACEFD 若設置成了有效的文件描述符( 0、 一、 2),則'set -x'調試選項生成的跟蹤輸出可被重定向。一般用來將跟蹤輸出到一個文件中
BASHOPTS 當前啓用的bash shell選項的列表
BASHPID 當前bash進程的PID
COLUMNS 當前bash shell實例所用終端的寬度
COMP_CWORD COMP_WORDS 變量的索引值,後者含有當前光標的位置
COMP_LINE 當前命令行
COMP_POINT 當前光標位置相對於當前命令起始的索引
COMP_KEY 用來調用shell函數補全功能的最後一個鍵
COMP_TYPE 一個整數值,表示所嘗試的補全類型,用以完成shell函數補全
COMP_WORDBREAKS Readline 庫中用於單詞補全的詞分隔字符
COMP_WORDS 含有當前命令行全部單詞的數組變量
COMPREPLY
COPROC 含有由shell函數生成的可能填充代碼的數組變量佔用未命名的協進程的I/O文件描述符的數組變量
DIRSTACK 含有目錄棧當前內容的數組變量
EMACS 設置爲't'時,代表emacs shell緩衝區正在工做,而行編輯功能被禁止
ENV 若是設置了該環境變量,在bash shell腳本運行以前會先執行已定義的啓動文件(僅用於當bash shell以POSIX模式被調用時)
EUID 當前用戶的有效用戶ID(數字形式)
FCEDIT 供fc命令使用的默認編輯器
FIGNORE 在進行文件名補全時能夠忽略後綴名列表,由冒號分隔
FUNCNAME 當前執行的shell函數的名稱
FUNCNEST 當設置成非零值時,表示所容許的最大函數嵌套級數(一旦超出,當前命令即被終止)
GLOBIGNORE 冒號分隔的模式列表,定義了在進行文件名擴展時能夠忽略的一組文件名
GROUPS 含有當前用戶屬組列表的數組變量
histchars 控制歷史記錄擴展,最多可有3個字符
HISTCMD 當前命令在歷史記錄中的編號
HISTCONTROL 控制哪些命令留在歷史記錄列表中
HISTFILE 保存shell歷史記錄列表的文件名(默認是.bash_history)
HISTFILESIZE
HISTTIMEFORMAT 最多在歷史文件中存多少行,若是設置了且非空,就用做格式化字符串,以顯示bash歷史中每條命令的時間戳
HISTIGNORE 由冒號分隔的模式列表,用來決定歷史文件中哪些命令會被忽略
HISTSIZE 最多在歷史文件中存多少條命令
HOSTFILE shell在補全主機名時讀取的文件名稱
HOSTNAME 當前主機的名稱
HOSTTYPE 當前運行bash shell的機器
IGNOREEOF shell 在退出前必須收到連續的EOF字符的數量(若是這個值不存在,默認是1)
INPUTRC Readline 初始化文件名(默認是.inputrc)
LANG shell的語言環境類別
LC_ALL 定義了一個語言環境類別,可以覆蓋LANG變量
LC_COLLATE 設置對字符串排序時用的排序規則
LC_CTYPE 決定如何解釋出如今文件名擴展和模式匹配中的字符
LC_MESSAGES 在解釋前面帶有$的雙引號字符串時,該環境變量決定了所採用的語言環境設置
LC_NUMERIC 決定着格式化數字時採用的語言環境設置
LINENO 當前執行的腳本的行號
LINES 定義了終端上可見的行數
MACHTYPE 用「 CPU公司系統」( CPU-company-system)格式定義的系統類型
MAPFILE 一個數組變量,當mapfile命令未指定數組變量做爲參數時,它存儲了mapfile所讀
入的文本
MAILCHECK shell查看新郵件的頻率(以秒爲單位,默認值是60)
OLDPWD shell以前的工做目錄
OPTERR 設置爲1時, bash shell會顯示getopts命令產生的錯誤
OSTYPE 定義了shell所在的操做系統
PIPESTATUS 含有前臺進程的退出狀態列表的數組變量
POSIXLY_CORRECT 設置了的話, bash會以POSIX模式啓動
PPID bash shell父進程的PID
PROMPT_COMMAND 設置了的話,在命令行主提示符顯示以前會執行這條命令
PROMPT_DIRTRIM 用來定義當啓用了\w或\W提示符字符串轉義時顯示的尾部目錄名的數量。被刪除的
目錄名會用一組英文句點替換
PS3 select命令的提示符
PS4 若是使用了bash的-x選項,在命令行以前顯示的提示信息
PWD 當前工做目錄
RANDOM 返回一個0~ 32767的隨機數(對其的賦值可做爲隨機數生成器的種子)
READLINE_LINE 當使用bind –x命令時,存儲Readline緩衝區的內容
READLINE_POINT 當使用bind –x命令時,表示Readline緩衝區內容插入點的當前位置
REPLY read命令的默認變量
SECONDS 自從shell啓動到如今的秒數(對其賦值將會重置計數器)
SHELL bash shell的全路徑名
SHELLOPTS 已啓用bash shell選項列表,列表項之間以冒號分隔
SHLVL shell的層級;每次啓動一個新bash shell,該值增長1
TIMEFORMAT 指定了shell的時間顯示格式
TMOUT select和read命令在沒輸入的狀況下等待多久(以秒爲單位)。默認值爲0,表示
無限長
TMPDIR 目錄名,保存bash shell建立的臨時文件
UID 當前用戶的真實用戶ID(數字形式)
當你在shell命令行界面中輸入一個外部命令時, shell必須搜索系統來找到對應的程序。 PATH環境變量定義了用於進行命令和程序查找的目錄。
[root@instance-3lm099to ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/java/jdk1.8.0_171//bin:/usr/local/java/jdk1.8.0_171//jre/bin:/usr/local/hbase/hbase-0.98.11-hadoop2/bin:/usr/local/hadoop/hadoop-1.1.2/bin:/root/bin
PATH中的目錄使用冒號分隔。
若是命令或者程序的位置沒有包括在PATH變量中,那麼若是不使用絕對路徑的話, shell是無法找到的。若是shell找不到指定的命令或程序,它會產生一個錯誤信息:
[root@instance-3lm099to ~]# redis
-bash: redis: command not found
問題是,應用程序放置可執行文件的目錄經常不在PATH環境變量所包含的目錄中。解決的辦法是保證PATH環境變量包含了全部存放應用程序的目錄。
能夠把新的搜索目錄添加到現有的PATH環境變量中,無需從頭定義。 PATH中各個目錄之間是用冒號分隔的。你只需引用原來的PATH值,而後再給這個字符串添加新目錄就好了。能夠參考下面的例子。
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin: /sbin:/bin:/usr/games:/usr/local/games $ $ PATH=$PATH:/home/christine/Scripts $ $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/ games:/usr/local/games:/home/christine/Scripts $ $ myprog The factorial of 5 is 120. $
將目錄加到PATH環境變量以後,你如今就能夠在虛擬目錄結構中的任何位置執行程序。
$ cd /etc $ $ myprog The factorial of 5 is 120 $
ps:若是但願子shell也能找到你的程序的位置,必定要記得把修改後的PATH環境變量導出。
一般將單點符也加入PATH環境變量。該單點符表明當前目錄 。
$ PATH=$PATH:. $ $ cd /home/christine/Old_Scripts $ $ myprog2 The factorial of 6 is 720 $
對PATH變量的修改只能持續到退出或重啓系統。
當你登陸Linux系統時, bash shell會做爲登陸shell啓動。登陸shell會從5個不一樣的啓動文件裏讀取命令:
/etc/profile文件是系統上默認的bash shell的主啓動文件。系統上的每一個用戶登陸時都會執行這個啓動文件。
若是你的bash shell不是登陸系統時啓動的(好比是在命令行提示符下敲入bash時啓動),那麼你啓動的shell叫做交互式shell。交互式shell不會像登陸shell同樣運行,但它依然提供了命令行提示符來輸入命令。
若是bash是做爲交互式shell啓動的,它就不會訪問/etc/profile文件,只會檢查用戶HOME目錄中的.bashrc文件。
最後一種shell是非交互式shell。系統執行shell腳本時用的就是這種shell。不一樣的地方在於它沒有命令行提示符。可是當你在系統上運行腳本時,也許但願可以運行一些特定啓動的命令。