export 可以檢視(顯示)Shell 環境變數。我們直接進入正題,先來看看執行 export 會輸出什麼內容:
[[email protected] ~]$ export
declare -x CVS_RSH="ssh"
declare -x GEM_HOME="/usr/local/rvm/gems/ruby-2.2.3"
declare -x GEM_PATH="/usr/local/rvm/gems/ruby-2.2.3:/usr/local/rvm/gems/[email protected]"
declare -x GOROOT="/home/roc/program/go"
declare -x G_BROKEN_FILENAMES="1"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/home/roc"
declare -x HOSTNAME="roclinux"
declare -x IRBRC="/usr/local/rvm/rubies/ruby-2.2.3/.irbrc"
declare -x JAVA_HOME="/usr/lib/jvm/jre-1.7.0-openjdk.x86_64"
declare -x LANG="zh_CN.gb2312"
declare -x LC_ALL="zh_CN.gb2312"
declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="roc"
declare -x LS_COLORS="rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lz=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.bz=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.rar=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.
yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:"
declare -x MAIL="/var/spool/mail/roc"
declare -x MY_RUBY_HOME="/usr/local/rvm/rubies/ruby-2.2.3"
declare -x OLDPWD="/home/roc/test/20160403"
declare -x PATH="/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin:/home/roc/program/yii/framework/:/home/roc/program/php/bin:/home/roc/bin:/home/roc/program/thrift/bin:/home/roc/program/go/bin:/home/roc/program/vim/bin:/home/roc/program/git/bin:/home/roc/bin:/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin:/home/roc/program/yii/framework/:/home/roc/program/php/bin:/home/roc/bin:/home/roc/program/thrift/bin:/home/roc/program/go/bin:/home/roc/program/vim/bin:/home/roc/program/git/bin:/usr/local/rvm/gems/ruby-2.2.3/bin:/usr/local/rvm/gems/[email protected]/bin:/usr/local/rvm/rubies/ruby-2.2.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/www/wdlinux/mysql/bin:/usr/local/rvm/bin:/home/roc/bin:/www/wdlinux/mysql/bin:/home/roc/bin"
declare -x PWD="/home/roc"
declare -x RUBY_VERSION="ruby-2.2.3"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="111.193.210.134 52932 22000"
declare -x SSH_CONNECTION="123.123.56.192 11887 116.255.245.206 22000"
declare -x SSH_TTY="/dev/pts/1"
declare -x TERM="screen-256color"
declare -x TMUX="/tmp/tmux-1001/default,35631,0"
declare -x TMUX_PANE="%25"
declare -x USER="roc"
declare -x _system_arch="x86_64"
declare -x _system_name="CentOS"
declare -x _system_type="Linux"
declare -x _system_version="6"
declare -x rvm_alias_expanded
declare -x rvm_bin_flag
declare -x rvm_bin_path="/usr/local/rvm/bin"
declare -x rvm_delete_flag
declare -x rvm_docs_type
declare -x rvm_file_name
declare -x rvm_gemstone_package_file
declare -x rvm_gemstone_url
declare -x rvm_hook
declare -x rvm_niceness
declare -x rvm_nightly_flag
declare -x rvm_only_path_flag
declare -x rvm_path="/usr/local/rvm"
declare -x rvm_prefix="/usr/local"
declare -x rvm_proxy
declare -x rvm_quiet_flag
declare -x rvm_ruby_alias
declare -x rvm_ruby_bits
declare -x rvm_ruby_configure
declare -x rvm_ruby_file
declare -x rvm_ruby_global_gems_path
declare -x rvm_ruby_make
declare -x rvm_ruby_make_install
declare -x rvm_ruby_mode
declare -x rvm_ruby_string
declare -x rvm_ruby_url
declare -x rvm_script_name
declare -x rvm_sdk
declare -x rvm_silent_flag
declare -x rvm_sticky_flag
declare -x rvm_system_flag
declare -x rvm_use_flag
declare -x rvm_user_flag
declare -x rvm_version="1.26.11 (master)"
declare -x rvm_wrapper_name
export 輸出的內容就是 bash 的所有環境變數了,滿滿的兩頁看來還真是不少呀。
export/set/env/declare 的區別
在 Linux 系統中,除了 export 之外,env、set 和 declare 這三個命令也可以顯示 Shell 中的變數。那這四個命令有什麼區別呢?
這個問題,我們需要從 Shell 變數說起。Shell 的變數,可以分為“環境變數”和“自定義變數”兩種型別,兩者的區別在於作用範圍不同。環境變數可以在其進程的子進程中繼續有效,而自定義變數的勢力範圍則無法延伸到其進程的子進程中。
好了,知道了環境變數和自定義變數的區別,我們正式開始介紹 export/env/set/declare 的區別:
-
env:顯示當前使用者的環境變數,但不會顯示其自定義變數。
-
export:功能同 env 一樣,也是顯示當前使用者的環境變數,只不過該命令的輸出是按變數名進行排序的。
-
declare:顯示當前 Shell 中定義的所有變數,包括使用者的環境變數和自定義變數,該命令的輸出按變數名進行排序。
-
set:功能同 declare 一樣,顯示當前 Shell 中定義的所有變數,包括使用者的環境變數和自定義變數。
根據上面的說明,我們可以得出下面的結論:
-
env 和 export 顯示的是環境變數。
-
set 和 declare 顯示的是環境變數和自定義變數。
我們以 set 和 declare 為例,來看一下是否真的是這樣:
[[email protected] ~]$ set > set.txt
[[email protected] ~]$ declare > declare.txt
[[email protected] ~]$ diff set.txt declare.txt
54c54
< _=clear
---
> _=set
可以看到,set 和 declare 的輸出幾乎是一樣的。唯一的區別就在於這個“下劃線變數”。下劃線變數(_)表示使用者上一次輸入的命令的最後一個引數。上面兩條命令之所以出現不同,是因為在執行 set 前執行了 clear 命令,而在執行 declare 之前,執行了 set 命令。
設定 Shell 環境變數
$PATH 環境變數是 Linux 系統中最常用的變數之一,我們先來看一下這個變數的內容:
[[email protected] ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
相信細心的同學已經觀察到了,$PATH 變數的值是由多個路徑所組成的,並且用冒號進行了分隔。那麼,問題來了,這些路徑的作用是什麼呢?
當使用者在 Linux 系統中直接輸入一個命令(如 date 命令),而沒有指定其絕對路徑時,Linux 就會求助於 $PATH 啦,Linux 會依次進入到 $PATH 變數所指定的各個路徑中,去尋找是否存在此命令(date 命令),如果找到了,就執行該命令;如果沒有找到,就直接退出,並提示使用者未找到該命令。
在運維工作中,用好 $PATH 變數是可以大大提升工作效率的。假如 /home/roc/operation_tools 資料夾下存放著我們自製的各種運維小工具,每次使用這些小工具時又不想總指定其絕對路徑,那麼,我們應該怎麼辦呢?沒錯,我們應該把這個路徑追加到 $PATH 變數中去,具體的做法是這樣:
export PATH=$PATH:/home/roc/operation_tools
上述命令執行成功後,我們的運維小工具就可以直接被 Linux 系統找到了。從此以後,當我們想使用這些運維小工具時,就再也不用指定絕對路徑啦。
讓你真正體會 export 的威力
不知道你是否注意到上面例子中的一個細節,那就是我們在設定 $PATH 環境變數時,使用了 export 命令。如果沒有使用 export,會有什麼問題嗎?
這個問題問得很好,這正好引出 export 的作用,那就是,使用 export 設定的變數就成為了環境變數,而沒有使用 export 設定的則是自定義變數。
下面我們通過一個範例來看一下:
#我們在當前Shell進程中指定了var1變數
[[email protected] ~]$ var1="hello"
[[email protected] ~]$ echo $var1
hello
#我們在當前Shell進程中又指定了var2變數
[[email protected] ~]$ var2="world"
[[email protected] ~]$ echo $var2
world
#我們通過export發布var1
[[email protected] ~]$ export var1
#我們進入到一個bash子進程中
[[email protected] ~]$ bash
#var1變數仍然有效, 而var2變數已經無效了
[[email protected] ~]$ echo $var1 # 輸出變數的值
hello
[[email protected] ~]$ echo $var2 # 什麼也沒有輸出
通過上面的範例,我們可以清楚地看到:環境變數可以在其進程的子進程中繼續有效,而自定義變數則無效。
誤操作惹的禍
“哎呀,不好了,我的 Linux 系統出問題了,我竟然連 cat 命令都沒辦法執行了,執行時總是提示我找不到命令,這是怎麼回事?我只是按照上面的範例執行了一下命令,就成這個樣子了,我該怎麼辦啊?”
“同學,讓我看看你到底執行的是什麼命令?”
“我執行的命令,很簡單,就是這個:”
$ export PATH=/home/to/operation_tools
“額,問題找到了,你的命令輸錯啦,來看正確的用法吧。
$ export PATH=$PATH:/home/to/operation_tools
再對比一下你的命令,你的命令中缺少了 $PATH,這樣會清空原來 $PATH 的內容,$PATH 中沒有了系統指定的路徑 Linux 就無法找到要執行的命令。這是一個多麼可怕的誤操作啊!大家一定要記住這個教訓呀,在設定 PATH 環境變數時要格外小心哦。