從編程語言的觀點看linux shell-變量的作用域,環境變量,位置變量
我們仍以BASH 為討論的shell 語言
每一種編程語言中,我們都會碰到變量的作用域的問題。(比如在函數中定義的變量在函數外不能使用的)
BASH 中也有類似的問題,局部變量和環境變量(全局變量)。
局部變量是普通的變量,僅在創建它的Shell中有效。
環境變量。我們更多的使用“環境變量”而不是“全局變量”,因為這個名稱更
能體現它的特點。環境變量對創建它的Shell及其派生出來的子進程都有效。或者說環境變量可以繼承,但它對其它與創建它的Shell沒有關系的Shell并不可見。
聲明環境變量:declare -x 變量名=值
??????????????????????????? export 變量名=值
??????????????????????????? export 已經定義的局部變量名
在談談另一類的重要變量,位置變量。函數,腳本等都需要參數,位置變量就是
用來獲得這些參數的。相當于其它編程語言的形參。
$0? 表示當前腳本文件名。
$1,$2,$3,........,$9,${10},.... 表示第1,2,3.......個參數。
$# 位置變量的個數
$* $@ 表示所有的位置變量。(當然,兩者還是有區別的。)
shell中的變量和運算符
1.什么是變量?
???
??? 這個就不用廢話了,shell中的變量跟其他高級語言中的變量概念是一樣的。
2.shell中變量的類型?
????
??? shell中的變量類型有:本地變量、環境變量、位置變量、標準變量、特殊變量。
??? 2.1.本地變量在shell腳本的生存周期中使用的變量(也就是登錄一個shell到退出,這個shell為生存周期)設置一個本地變量格式為:變量名=變量,顯示一個變量:echo ${變量名}也可以不要大括號,顯示本地所有變量:set就可以,本地變量還可以設置為只讀的:readonly 變量名,這時的變量就具有只讀屬性,如果在shell下運行命令readonly,就會顯示當前環境下所有的只讀變量。
???
??? 2.2.環境變量用于所有的用戶進程(也就shell下所有的子進程),這個就有點像windows中的環境變量了(系統–>高級–>環境變量),環境變量一般保存在$HOME/.bash_profile和/etc/profile中,前者是只適用于當前用戶,后者適用于所有用戶設置一個環境變量用export,比喻我們這里設置一個環境變量:export pagename=”ghostwwl”這樣就設置了一個叫做pagename的環境變量,我們可以通過env這個命令來查看,還有就是可以直接通過運行export來查看。
??? 2.3.位置變量也就相當于程序中的參數(也就相當于C中的argv),在shell中位置變量一般允許$0-$9一共10個,超過10個的,嘿嘿就必須使用其他方式了。很顯然這里$0就是腳本的名字了,從$1開始就是后面的參數了。說白了也就是那個argv了。
我們這里舉個小例子,比喻有shell程序aa.sh于下:
??? #!/bin/bash
??? #named aa
??? echo “程序名為: $0″
??? echo “姓名為: $1″
??? echo “年齡為: $2″
??? echo “所屬省分為: $3″
??? echo “所在城市為: $4″
??? echo “第五個參數為: $5″
我們運行這個腳本 ./aa.sh ghostwwl 24 Hubei Wuhan 顯示結果為:
??? 程序名為: ./aa.sh
??? 姓名為: ghostwwl
??? 年齡為: 24
??? 所屬省分為: Hubei
??? 所在城市為: Wuhan
??? 第五個參數為:
可以看出因為第五個參數沒有所以就為空了
當然我們可以在腳本中系統命令傳遞參數,比喻下面一句:
find /usr/share/realpaly -name $1 -print
這個腳本語句就可以在腳本中對文件目錄/usr/share/realplay中文件名為第一個參數的文件進行查找。
說這么多他*的就是參數,搞半天。
??
??? 2.4.標準變量,也就是bash環境建立的一些標準環境的標量,他會自動去解析,基本都在/etc/profile中定義了有EXINIT,HOME,IFS,LOGNAME,MAIL,MAILCHECK等。
??? EXINIT 是vi編輯器初始化運行的一些參數
??? HOME 這個傻子都知道,就是偶們的主目錄
??? IFS 一個個字段域之間用什么隔開的理論上可以任意字符,比喻/usr/bin;/usr/sbin
這里的IFS就是”;”了。
??? LOGNAME 看名字就知道 是登錄名可以用 echo $LOGNAME 來查看
??? MAIL 表示當用戶的郵箱路徑
??? MAILCHECK 表示每間隔多少秒檢查一次收件箱
還有一堆標準變量PATH,tz,PS1,PS2,PWD等等,我這里就不全部寫了,自己去找資料看,相信應該蠻好找的。
??? 2.5.特殊變量
$# 表示傳遞到腳本的參數列表
$* 以一個字符串顯示所有向腳本傳遞的參數,跟位置變量不同的是這里參數可超過9個。
$$ 表示當前運行腳本的進程ID號
$! 表示后臺運行的一個進程的ID號
$@ 與$#相同,但是使用時加引號,并在引號中返回每一個參數
$- 顯示shell使用的當前選項,與set命令相同
$? 顯示最后命令運行的推出狀態,0表示沒有錯誤,其他任何值表示有錯誤?
3.shell中的變量替換
??? 這里說一下變量替換這個經常用到,其實就是用變量的值替 換他的名字,顯示變量的時候就是這個,可以用:
為了試驗我們先定義一個變量haha=”**** you”
???? a.${變量名}來搞定(這里的大括號可要可不要,不過偶一般都加)
???? b.${變量名:+變量值}這個表示如果前面的變量值不為空,則顯示變量值,否則置空,比喻echo ${name:+”ghostwwl”}這樣可不管你以前有沒有對name賦過值都會顯示這里的”ghostwwl”
???? c.${變量名:?錯誤信息}這個表示當變量名存在,就是變量的值,不存在就顯示問號后面的錯誤信息比喻echo ${age:+”No defined variable age”}這個因為age不存在所以它會顯示錯誤信息age:No defined variable age
???? d.${變量名:-變量值}這個表示如果如果變量名沒有設置,就用這里給出變量值來代替,顯然如果設置了肯定就是返回原來設置的值:比喻echo ${age:-24}因為age變量沒有設置,所以它會用24去代替,如果是echo ${haha:-”hello”}這里會顯示原來所賦的值”**** you”記得不要跟b中的情況搞混。
???? e.${變量名:=變量值}表示如果沒有設置變量名這個變量,就設置它的值,比喻echo ${age:=24}因為沒有設置age這個值,所以運行這句的時候會賦值并顯示。當然這樣賦值以后就可以把age當正常變量用了,也就是這時我們有haha和age這兩個變量了。
??? 就這五種了(當然如果把第一種去掉大括號,就6種了),開始可能并不習慣,用多了就習慣了,啊哈哈!
4.清除變量(unset)
??? 能定義變量當然也就能刪除變量了,比喻我們要刪除那個haha,因為值為”**** you”不太文明,我們可以用:unset haha 從這里就可以看出清除變量用unset 變量名。
??? 這里我們要注意,設置了readonly的只讀變量不能取消也不能重新設置值。
我們這里再來把前面個例子改一下:
??? #!/bin/bash
??? #named aa
??? echo “程序名為: $0″
??? echo “姓名為: $1″
??? echo “年齡為: $2″
??? echo “所屬省分為: $3″
??? echo “所在城市為: $4″
??? echo “參數個數為: $#”
??? echo “腳本參數為: $*”
??? echo “腳本進程ID為: $$”
我們再來運行這個腳本 ./aa.sh ghostwwl 24 hubei wuhan 結果為:
??? 程序名為: ./aa.sh
??? 姓名為: ghostwwl
??? 年齡為: 24
??? 所屬省分為: hubei
??? 所在城市為: wuhan
??? 腳本參數個數為: 4
??? 腳本參數為: ghostwwl 24 hubei wuhan
??? 腳本進程ID為: 212
5.影響變量的一些命令
??? 5.1 declare 創建或顯示變量
??????? 參數-f 只顯示函數名
??????? 參數-r 創建只讀變量(typeset也可以)
??????? 參數-x 創建轉出變量
??????? 參數-i 創建整數變量
??????? 如果參數中使用+來代替-,表示選項的含義相反。
????
??? 5.2 export 創建環境變量
??????? 參數– 表明選項結束,所有后面的參數都是實參
??????? 參數-f 表示在”變量-值”對照中的變量是一個函數名
??????? 參數-n 表示把全局變量轉換成局部變量(也就是本地變量)。
??????? 參數-p 顯示全局變量列表
?
??? 5.3 readonly 創建或顯示只讀變量
??????? 參數– 表示選項結束
??????? 參數-f 創建只讀變量
??? 5.4 set 設置或者重設各種shell
??? 5.5 shift [n] 用來移動或調整位置變量,使$4賦給$3(也就是全都向前面移動一次),這個里面的n表示移動幾位,默認是移動一位。
??? 5.6 typeset 這個就跟declare相同了
??? 5.7 unset 清除變量的定義
??????? 參數– 表示選項結束
??????? 參數-f 刪除只讀變量,但是不能sehll環境中制定的變量和函數。
6.shell的運算符
?? 6.1 位運算 ~,>>,<<,&,|,^ 一看就知道分別是取反,左移,右移,與,或,異或。
?? 6.2 $[]表示對[]中的表達式求值和$(())相等的。
?? 6.3 邏輯運算符 &&,||,>,<,==,!= 是人都看得懂跟C里一樣的。?
?? 6.4 賦值運算符 =,+=,-=,*=,/=,%=,&=,|=,<<=,>>=,^= 跟其他語言差不多一看就明白的。當然表達式賦值let $a=$b+$c這種形式。
?? 6.5 運算符的優先級我就不想廢話了,都跟其他語言差不多的,自己去找。
http://why-gudu.spaces.live.com/Blog/cns!1pziotErZQfm5-4NtdB7DJ3w!155.entry
http://bbs.topsage.com/dv_rss_xm_119_195915_1.html
?