Shell脚本攻略02-玩转变量与环境变量
概述
變量是任何一種編程語言都必不可少的組成部分,用于存放各類數(shù)據(jù)。
腳本語言通常不需要在使用變量之前聲明其類型。只需要直接賦值就可以了。
在Bash中,每一個(gè)變量的值都是字符串。
無論你給變量賦值時(shí)有沒有使用引號,值都會以字符串的形式存儲。
有一些特殊的變量會被shell環(huán)境和操作系統(tǒng)環(huán)境用來存儲一些特別的值,這類變量就被稱為環(huán)境變量。
理論知識
變量采用常見的命名方式進(jìn)行命名。當(dāng)應(yīng)用程序執(zhí)行時(shí),它接收一組環(huán)境變量。
可以使用env命令查看所有與終端相關(guān)的環(huán)境變量。
[root@entel1 ~]# env HOSTNAME=entel1 TERM=xterm SHELL=/bin/bash HISTSIZE=1000 .......省略對于進(jìn)程來說,其運(yùn)行時(shí)的環(huán)境變量可以使用下面的命令來查看:
cat /proc/$PID/environ其中,將PID設(shè)置成相關(guān)進(jìn)程的進(jìn)程ID(PID總是一個(gè)整數(shù))。
如何獲取$PID呢?
假設(shè)有一個(gè)叫做gedit的應(yīng)用程序正在運(yùn)行。我們可以使用pgrep命令獲得gedit的進(jìn)程ID:
$ pgrep gedit 12501那么,你就可以通過以下命令獲得與該進(jìn)程相關(guān)的環(huán)境變量:
$ cat /proc/12501/environ GDM_KEYBOARD_LAYOUT=usGNOME_KEYRING_PID=1560USER=slynuxHOME=/home/slynux .........環(huán)境變量遠(yuǎn)不止這些,只是由于對頁面篇幅的限制,在這里刪除了其他很多環(huán)境變量。
pgrep 用法
[root@entel2 ~]# pgrep --help pgrep: invalid option -- '-' Usage: pgrep [-flvx] [-d DELIM] [-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST][-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] [PATTERN]pgrep程序檢查在系統(tǒng)的中活動(dòng)進(jìn)程,報(bào)告進(jìn)程屬性匹配命令行上指定條件的進(jìn)程的ID。
pgrep 查找的是程序名,而不包其參數(shù)
pgrep相當(dāng)于 ps -eo pid,cmd |awk '{print $1,$2}'|grep keyword
如果pgrep不是很熟悉,可以用ps -ef
[root@entel2 ~]# ps -ef|less UID PID PPID C STIME TTY TIME CMD root 1 0 0 Oct25 ? 00:00:15 /sbin/init root 2 0 0 Oct25 ? 00:00:00 [kthreadd]取 第二列 PID
舉例:
[root@entel2 ~]# pgrep java 4309 [root@entel2 ~]# cat /proc/4309/environ APP_XMX_SIZE_zmcDaemon=128MHOSTNAME=tbpr_app1SHELL=/bin/bashTERM=vt100HISTSIZE=1000SSH_CLIENT=172.25.246.66 42562 22OLDPWD=/home/settWeb/zmc_agent/daemonSSH_TTY=/dev/pts/9USER=settWebJRE_HOME=/usr/lib/jvm/jdk1.7.0_80/jreLS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.......省略上面的命令返回一個(gè)包含環(huán)境變量以及對應(yīng)變量值的列表。每一個(gè)變量以name=value的形式來描述,彼此之間由null字符(\0)分隔。
看起來是不是很懵逼,一團(tuán)亂糟糟的很難以查看。
如果你將\0替換成\n,那么就可以將輸出重新格式化,使得每一行顯示一組“變量=值”。替換可以使用tr命令來實(shí)現(xiàn):
[root@entel2 ~]# cat /proc/4309/environ |tr '\0' '\n' APP_XMX_SIZE_zmcDaemon=128M HOSTNAME=tbpr_app1 SHELL=/bin/bash TERM=vt100 HISTSIZE=1000 SSH_CLIENT=172.25.246.66 42562 22 OLDPWD=/home/settWeb/zmc_agent/daemon SSH_TTY=/dev/pts/9 USER=settWeb JRE_HOME=/usr/lib/jvm/jdk1.7.0_80/jre LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;....省略對變量和環(huán)境變量進(jìn)行賦值
變量賦值
變量可以通過以下方式進(jìn)行賦值:
var=valuevar是變量名, value是賦給變量的值。
如果value不包含任何空白字符(例如空格),那么它就不需要使用引號進(jìn)行引用,否則必須使用單引號或雙引號。
注意, var = value不同于var=value。把var=value寫成var = value是一個(gè)常見的錯(cuò)誤,但前者是賦值操作,后者則是相等操作。
在變量名之前加上$前綴就可以打印出變量的內(nèi)容:
var="value" #給變量var賦值 echo $var或者
echo ${var}輸出value
栗子:
[root@entel1 ~]# cat -b var.sh 1 #!/bin/bash2 var="xiaogongjiang bash"3 var2=xiaogongjaing4 var3 = wrong_use5 echo $var6 echo ${var2}7 echo $var3 [root@entel1 ~]# ./var.sh ./var.sh: line 4: var3: command not found xiaogongjiang bash xiaogongjaing[root@entel1 ~]#可以在printf或echo命令的雙引號中引用變量值。
[root@entel1 Templates]# cat variables.sh #!/bin/bash lesson=shell count=100 echo "we have ${count} $lesson ,output by echo" #換行 \n printf "we have $count $lesson output by printf \n" [root@entel1 Templates]# ./variables.sh we have 100 shell ,output by echo we have 100 shell output by printf [root@entel1 Templates]#注意:
使用單引號時(shí),變量不會被擴(kuò)展(expand),將依照原樣顯示。這意味著:
$ echo '$var' will print $var但如果變量var已經(jīng)定義過,那么$ echo "$var"會打印出該變量的值;
如果沒有定義過,則什么都不打印。
環(huán)境變量賦值
環(huán)境變量是未在當(dāng)前進(jìn)程中定義,而從父進(jìn)程中繼承而來的變量。
例如環(huán)境變量,HTTP_PROXY,它定義了互聯(lián)網(wǎng)連接應(yīng)該使用哪個(gè)代理服務(wù)器。
該環(huán)境變量通常被設(shè)置成:
HTTP_PROXY=192.168.1.23:3128 export HTTP_PROXYexport命令用來設(shè)置環(huán)境變量。至此之后,從當(dāng)前shell腳本執(zhí)行的任何應(yīng)用程序都會繼承這個(gè)變量。
我們可以按照自己的需要,在執(zhí)行的應(yīng)用程序或者shell腳本中導(dǎo)出特定的變量。
在默認(rèn)情況下,有很多標(biāo)準(zhǔn)環(huán)境變量可供shell使用。
PATH就是其中之一。
在給出所要執(zhí)行的命令后, shell會自動(dòng)在PATH環(huán)境變量所包含的目錄列表中(各目錄路徑之間以冒號分隔)查找對應(yīng)的可執(zhí)行文件。
PATH通常定義在/etc/environment或/etc/profile或~/.bashrc中。
PATH中添加一條新路徑
如果需要在PATH中添加一條新路徑,可以使用:
$ export PATH="$PATH:/home/user/bin"也可以使用
$ PATH="$PATH:/home/user/bin" $ export PATH這樣,我們就將/home/user/bin添加到了PATH中。
還有一些眾所周知的環(huán)境變量: HOME、 PWD、 USER、 UID、 SHELL等
Addition
下面我們再多看些有關(guān)標(biāo)準(zhǔn)變量和環(huán)境變量的技巧。
獲得字符串長度${#}
[root@entel1 Templates]# cat test.sh #!/bin/bash var=xiaogongjiang echo "var's length ${#var}" [root@entel1 Templates]# ./test.sh var's length 13識別當(dāng)前所使用的shell
可以用下面的方法獲知當(dāng)前使用的是哪種shell:
echo $SHELL也可以用
echo $0檢查是否為超級用戶
UID是一個(gè)重要的環(huán)境變量,可以用于檢查當(dāng)前腳本是以超級用戶還是以普通用戶的身份運(yùn)行的。
root用戶的UID是0。
例如:
[root@entel1 Templates]# cat test.sh #!/bin/bash #檢測用戶是否是root用戶 #[] 兩側(cè)記得帶空格 [$UID -ne 0] 會報(bào)錯(cuò) if [ $UID -ne 0 ]; then echo Non root user else echo Root user fi [root@entel1 Templates]# ./test.sh Root user修改Bash提示字符串( username@hostname:~$)
http://blog.csdn.net/yangshangwei/article/details/52928009
當(dāng)我們打開終端或是運(yùn)行shell時(shí),會看到類似于user@hostname:/home/$的提示字符串。
不同GNU/Linux發(fā)布版中的提示及顏色略有不同。我們可以利用PS1環(huán)境變量來定制提示文本。
默認(rèn)的shell提示文本是在文件~/.bashrc中的某一行設(shè)置的。
? 可以使用如下命令列出設(shè)置變量PS1的那一行:
$ cat ~/.bashrc | grep PS1 PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '? 如果要設(shè)置一個(gè)定制的提示字符串,可以輸入:
$ PS1="PROMPT>" PROMPT> Type commands here #提示字符串已經(jīng)改變? 我們可以利用類似\e[1;31的特定轉(zhuǎn)義序列來設(shè)置彩色的提示字符串
還有一些特殊的字符可以擴(kuò)展成系統(tǒng)參數(shù)。
例如: \u可以擴(kuò)展為用戶名, \h可以擴(kuò)展為主機(jī)名,而\w可以擴(kuò)展為當(dāng)前工作目錄。
使用函數(shù)添加環(huán)境變量
環(huán)境變量通常用于存儲路徑列表,這些路徑用于搜索可執(zhí)行文件、庫文件等。
例如$PATH、$LD_LIBRARY_PATH,它們通常看起來像這樣:
PATH=/usr/bin;/bin LD_LIBRARY_PATH=/usr/lib;/lib這意味著只要shell需要運(yùn)行二進(jìn)制可執(zhí)行文件時(shí),它會首先查找/usr/bin,然后是/bin。
場景舉例
當(dāng)你必須使用源代碼編譯生成程序并將其安裝到某個(gè)特定路徑中時(shí),有項(xiàng)極其常見的任務(wù)就是將該程序的bin目錄加入PATH環(huán)境變量。
假設(shè)我們要將myapp安裝到/opt/myapp,它的二進(jìn)制文件在bin目錄中,庫文件在lib目錄中。
實(shí)現(xiàn)方法
export PATH=/opt/myapp/bin:$PATH export LD_LIBRARY_PATH=/opt/myapp/lib;$LD_LIBRARY_PATHPATH和LD_LIBRARY_PATH現(xiàn)在看起來應(yīng)該像這樣:
PATH=/opt/myapp/bin:/usr/bin:/bin LD_LIBRARY_PATH=/opt/myapp/lib:/usr/lib;/lib不過我們可以把下面的函數(shù)加入.bashrc-,讓一切變得更輕松些:
prepend() { [ -d "$2" ] && eval $1=\"$2':'\$$1\" && export $1; }像下面這樣來使用該函數(shù):
prepend PATH /opt/myapp/bin prepend LD_LIBRARY_PATH /opt/myapp/lib函數(shù)分析
我們定義了名為prepend()的函數(shù),它首先檢查該函數(shù)第二個(gè)參數(shù)所指定的目錄是否存在。
如果存在, eval表達(dá)式將第一個(gè)參數(shù)所指定的變量值設(shè)置成第二個(gè)參數(shù)的值加上“ :”(路徑分隔符),隨后再跟上首個(gè)參數(shù)的原始值。
完善函數(shù)
不過,有一點(diǎn)需要留意。在進(jìn)行添加時(shí),如果變量為空,則會在末尾留下一個(gè)“ :”。
要解決這個(gè)問題,可以將該函數(shù)再進(jìn)行一些修改
prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }在這個(gè)函數(shù)中,我們引入了一種shell參數(shù)擴(kuò)展的形式:
${parameter:+expression}如果parameter有值且不為空,則使用expression的值。
通過這次修改,在追加環(huán)境變量時(shí),當(dāng)且僅當(dāng)舊值存在,才會增加。
總結(jié)
以上是生活随笔為你收集整理的Shell脚本攻略02-玩转变量与环境变量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle-表分析和索引分析解读
- 下一篇: Shell脚本攻略03-使用shell进