shell變量詳解

本文轉(zhuǎn)載自Hello外驱,Barry的shell變量詳解
1 shell變量基礎(chǔ)
shell變量是一種很“弱”的變量璧尸,默認(rèn)情況下窜护,一個(gè)變量保存一個(gè)串助赞,shell不關(guān)心這個(gè)串是什么含義买羞。所以若要進(jìn)行數(shù)學(xué)運(yùn)算,必須使用一些命令例如let雹食、declare畜普、expr、雙括號(hào)等群叶。shell變量可分為兩類(lèi):局部變量和環(huán)境變量吃挑。局部變量只在創(chuàng)建它們的shell中可用钝荡。而環(huán)境變量則可以在創(chuàng)建它們的shell及其派生出來(lái)的任意子進(jìn)程中使用。有些變量是用戶(hù)創(chuàng)建的舶衬,其他的則是專(zhuān)用shell變量埠通。變量名必須以字母或下劃線(xiàn)字符開(kāi)頭。其余的字符可以是字母逛犹、數(shù)字(0~9)或下劃線(xiàn)字符端辱。任何其他的字符都標(biāo)志著變量名的終止。名字是大小寫(xiě)敏感的圾浅。給變量賦值時(shí)掠手,等號(hào)周?chē)荒苡腥魏慰瞻追榱私o變量賦空值狸捕,可以在等號(hào)后跟一個(gè)換行符喷鸽。用set命令可以查看所有的變量,unset var命令可以清除變量var灸拍,var相當(dāng)于沒(méi)有定義過(guò)做祝。readonly var可以把var變?yōu)橹蛔x變量,定義之后不能對(duì)var進(jìn)行任何更改鸡岗。對(duì)shell變量的引用方式很多混槐,用這些方式可以方便的獲取shell變量的值,變量值的長(zhǎng)度轩性,變量的一個(gè)字串声登,變量被部分替換后的值等等。shell變量常見(jiàn)引用方式如下:

2 環(huán)境變量
環(huán)境變量的定義方法如下:
var=value
export var
shell在初始化的時(shí)候會(huì)在執(zhí)行profile等初始化腳本揣苏,腳本中定義了一些環(huán)境變量悯嗓,這些變量會(huì)在創(chuàng)建子進(jìn)程時(shí)傳遞給子進(jìn)程。
用env命令可以查看當(dāng)前的環(huán)境變量卸察。常用的系統(tǒng)環(huán)境變量如下:
(下劃線(xiàn)) 上一條命令的最后一個(gè)參數(shù)
BASH 展開(kāi)為調(diào)用bash實(shí)例時(shí)使用的全路徑名
CDPATH cd命令的搜索路徑脯厨。它是以冒號(hào)分隔的目錄列表,shell通過(guò)它來(lái)搜索cd命令指定的目標(biāo)目錄坑质。例如.:~:/usr
EDITOR 內(nèi)置編輯器emacs合武、gmacs或vi的路徑名
ENV 每一個(gè)新的bash shell(包括腳本)啟動(dòng)時(shí)執(zhí)行的環(huán)境文件。通常賦予這個(gè)變量的文件名是.bashrc涡扼。
EUID 展開(kāi)為在shell啟動(dòng)時(shí)被初始化的當(dāng)前用戶(hù)的有效ID
GROUPS 當(dāng)前用戶(hù)所屬的組
HISTFILE 指定保存命令行歷史的文件稼跳。默認(rèn)值是~/.bash_history。如果被復(fù)位壳澳,交互式shell退出時(shí)將不保存命令行歷史
HISTSIZE 記錄在命令行歷史文件中的命令數(shù)岂贩。默認(rèn)是500
HOME 主目錄。未指定目錄時(shí),cd命令將轉(zhuǎn)向該目錄
IFS 內(nèi)部字段分隔符萎津,一般是空格符卸伞、制表符和換行符,用于由命令替換锉屈,循環(huán)結(jié)構(gòu)中的表和讀取的輸入產(chǎn)生的詞的字段劃分
LANG 用來(lái)為沒(méi)有以L(fǎng)C
開(kāi)頭的變量明確選取的種類(lèi)確定locale類(lèi)
OLDPWD 前一個(gè)工作目錄
PATH 命令搜索路徑荤傲。一個(gè)由冒號(hào)分隔的目錄列表,shell用它來(lái)搜索命令颈渊,一個(gè)普通值為 /usr/gnu/bin:/usr/local/bin:/usr/ucb:/usr/bin
PPID 父進(jìn)程的進(jìn)程ID
PS1 主提示符串遂黍,默認(rèn)值是$
PS2 次提示符串,默認(rèn)值是>
PS3 與select命令一起使用的選擇提示符串俊嗽,默認(rèn)值是#?
PS4 當(dāng)開(kāi)啟追蹤時(shí)使用的調(diào)試提示符串雾家,默認(rèn)值是+。追蹤可以用set –x開(kāi)啟
PWD 當(dāng)前工作目錄绍豁。由cd設(shè)置
RANDOM 每次引用該變量芯咧,就產(chǎn)生一個(gè)隨機(jī)整數(shù)。隨機(jī)數(shù)序列可以通過(guò)給RANDOM賦值來(lái)初始化竹揍。如果RANDOM被復(fù)位敬飒,即使隨后再設(shè)置,它也將失去特定的屬性
REPLY 當(dāng)沒(méi)有給read提供參數(shù)時(shí)設(shè)置
SHELL 當(dāng)調(diào)用shell時(shí)芬位,它掃描環(huán)境變量以尋找該名字无拗。shell給PATH、PS1昧碉、PS2英染、MAILCHECK和IFS設(shè)置默認(rèn)值。HOME和MAIL由login(1)設(shè)置
SHELLOPTS 包含一列開(kāi)啟的shell選項(xiàng)被饿,比如braceexpand税迷、hashall、monitor等
UID 展開(kāi)為當(dāng)前用戶(hù)的用戶(hù)ID锹漱,在shell啟動(dòng)時(shí)初始化
3 數(shù)值變量
shell中默認(rèn)把變量值當(dāng)作字符串,例如:
age=22
age=${age}+1
echo ${age}
輸出結(jié)果為22+1慕嚷,而不是23哥牍,因?yàn)閟hell將其解釋為字符串,而不是數(shù)學(xué)運(yùn)算喝检。
可以用let命令使其進(jìn)行數(shù)學(xué)運(yùn)算嗅辣,例如:
let age=${age}+1
也可以用declare把變量定義為整型。例如:
declare -i age=22
這里就用 -i 選項(xiàng)把a(bǔ)ge定義為整型的了挠说。此后每次運(yùn)算澡谭,都把a(bǔ)ge的右值識(shí)別為算術(shù)表達(dá)式或數(shù)字。
4 數(shù)組
在shell中可以使用數(shù)組损俭,例如:
array[0]=0
array[1]=1
array[2]=2
則array就是一個(gè)數(shù)組蛙奖,也可以這樣給數(shù)組初始化:
array=(0 1 2) // 元素之間以空格分隔
可以通過(guò) ${array[$i]}來(lái)訪(fǎng)問(wèn)array中某個(gè)元素潘酗,${array[]} 的返回值即數(shù)組的所有元素組成的串,${#array[]} 的返回值即數(shù)組的元素個(gè)數(shù)雁仲,${array[*]:0:2} 返回第一個(gè)和第二個(gè)元素組成的串仔夺。0表示開(kāi)始的位置,2表示要返回的元素個(gè)數(shù)攒砖,開(kāi)始位置可以為0-2(0減去2)之類(lèi)的缸兔,表示從倒數(shù)第二個(gè)元素開(kāi)始。
下面寫(xiě)個(gè)稍微復(fù)雜點(diǎn)的例子:
復(fù)制代碼

1 #!/bin/bash
2 for ((i=0; i<100; i++))
3 do
4 array[$i]=$i
5 done
6 for ((i=0; i<100; i++))
7 do
8 echo ${array[$i]}
9 done

復(fù)制代碼

如果要使用二維數(shù)組甚至三維數(shù)組該怎么實(shí)現(xiàn)呢吹艇,那就需要用eval命令來(lái)模擬數(shù)組的功能了惰蜜。
eval命令的作用是掃描命令兩次再執(zhí)行,如果不使用eval受神,只掃描一次抛猖,然后執(zhí)行÷房耍看個(gè)例子:
root@suse:~$ name=Barry
root@suse:~$ $name=hello
Barry=hello: command not found
為什么第二句給Barry變量賦值會(huì)出錯(cuò)呢樟结?從報(bào)錯(cuò)信息可以發(fā)現(xiàn)shell并沒(méi)有識(shí)別這是個(gè)賦值語(yǔ)句,而是把Barry=hello當(dāng)作一個(gè)命令來(lái)執(zhí)行精算,當(dāng)然會(huì)報(bào)錯(cuò)瓢宦。為什么不能識(shí)別這是賦值語(yǔ)句呢?第一次掃描時(shí)灰羽,因?yàn)閽呙璧?符號(hào)驮履,所以不能把這句當(dāng)作賦值語(yǔ)句,賦值語(yǔ)句的左邊總是一個(gè)變量名廉嚼,而不應(yīng)該是$開(kāi)頭的玫镐。所以第一次掃描僅僅識(shí)別了$name變量,并做了替換怠噪,而并沒(méi)有認(rèn)識(shí)到賦值語(yǔ)句恐似。
如果使用eval $name=hello呢?
root@suse:~$ name=Barry
root@suse:~$ $name=hello
Barry=hello: command not found
root@suse:~$ eval $name=hello
root@suse:~$ echo $Barry
hello
可見(jiàn)使用了eval之后傍念,對(duì) $name=hello 第一次掃描替換了$name矫夷,沒(méi)有識(shí)別賦值語(yǔ)句,第二次掃描識(shí)別是賦值語(yǔ)句憋槐,然后執(zhí)行∷海現(xiàn)在大約可以想到怎樣用eval實(shí)現(xiàn)二維數(shù)組了。
下面實(shí)現(xiàn)的二維數(shù)組每一行代表一個(gè)人的信息記錄阳仔,包括姓名忧陪,年齡。
復(fù)制代碼

1 for ((i=0; i<2; i++))
2 do
3 for ((j=0; j<2; j++))
4 do
5 read man$i$j
6 done
7 done
8 echo "next print:"
9 for ((i=0; i<2; i++))
10 do
11 for ((j=0; j<2; j++))
12 do
13 eval echo -n "$man$i$j:"
14 done
15 printf "\n"
16 done

復(fù)制代碼

5 特殊變量
$0:當(dāng)前腳本的文件名
$num:num為從1開(kāi)始的數(shù)字,$1是第一個(gè)參數(shù)嘶摊,$2是第二個(gè)參數(shù)延蟹,${10}是第十個(gè)參數(shù)
$#:傳入腳本的參數(shù)的個(gè)數(shù)
$*:所有的位置參數(shù)(作為單個(gè)字符串)
$@:所有的位置參數(shù)(每個(gè)都作為獨(dú)立的字符串)。
$?:當(dāng)前shell進(jìn)程中更卒,上一個(gè)命令的返回值等孵,如果上一個(gè)命令成功執(zhí)行則$?的值為0,否則為其他非零值蹂空,常用做if語(yǔ)句條件
$$:當(dāng)前shell進(jìn)程的pid
$!:后臺(tái)運(yùn)行的最后一個(gè)進(jìn)程的pid
$-:顯示shell使用的當(dāng)前選項(xiàng)
$_:之前命令的最后一個(gè)參數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俯萌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子上枕,更是在濱河造成了極大的恐慌咐熙,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辨萍,死亡現(xiàn)場(chǎng)離奇詭異棋恼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)锈玉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)爪飘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拉背,你說(shuō)我怎么就攤上這事师崎。” “怎么了椅棺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵犁罩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我两疚,道長(zhǎng)床估,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任诱渤,我火速辦了婚禮丐巫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勺美。我一直安慰自己鞋吉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布励烦。 她就那樣靜靜地躺著,像睡著了一般泼诱。 火紅的嫁衣襯著肌膚如雪坛掠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音屉栓,去河邊找鬼舷蒲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛友多,可吹牛的內(nèi)容都是我干的牲平。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼域滥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纵柿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起启绰,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤昂儒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后委可,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體渊跋,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年着倾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拾酝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卡者,死狀恐怖蒿囤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虎眨,我是刑警寧澤蟋软,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站嗽桩,受9級(jí)特大地震影響岳守,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碌冶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一湿痢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扑庞,春花似錦譬重、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至栅隐,卻和暖如春塔嬉,著一層夾襖步出監(jiān)牢的瞬間玩徊,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工谨究, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恩袱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓畔塔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鸯屿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容