轉(zhuǎn)帖|行業(yè)資訊|編輯:龔雪|2015-10-12 15:23:37.000|閱讀 574 次
概述:shell腳本可以直接與操作系統(tǒng)內(nèi)核打交道,從而完成任意復(fù)雜的任務(wù),讓我們一起來(lái)看看shell是如何完成某些特殊復(fù)雜的功能的。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
學(xué)習(xí)linux操作系統(tǒng)最讓人著迷的事情莫過(guò)于shell腳本編程,這是因?yàn)槿绻瓿赡承?fù)雜的功能,單純地通過(guò)GUI操作不可能達(dá)到,shell腳本可以直接與操作系統(tǒng)內(nèi)核打交道,從而完成任意復(fù)雜的任務(wù)。shell有很多種,最常用的是Bash (Bourne Again Shell),它是Linux操作系統(tǒng)默認(rèn)的shell環(huán)境。
在linux環(huán)境中,需要區(qū)分一下root用戶(hù)與一般用戶(hù)的命令行顯示:
//root用戶(hù)與一般用戶(hù)顯示有一些差異 //root用戶(hù)命令行以#結(jié)尾 root@sparkmaster:~# su zhouzhihu //一般用戶(hù)命令行以$符號(hào)結(jié)尾 zhouzhihu@sparkmaster:/root$ exit exit root@sparkmaster:~#
如下圖:
現(xiàn)在讓我們來(lái)編寫(xiě)第一個(gè)shell程序吧
root@sparkmaster:~/ShellLearning/chapter09# vi HelloWorld.sh
就兩行內(nèi)容:
#!/bin/bash echo "Hello Shell"
那完成后如果執(zhí)行shell腳本程序呢?有兩種方式,一種是通過(guò)sh命令,另外一種是自執(zhí)行方式。下面給出了具體演示
//完成后直接利用sh命令執(zhí)行 root@sparkmaster:~/ShellLearning/chapter09# sh HelloWorld.sh Hello Shell //自執(zhí)行(self execute)方式,由于沒(méi)有給文件加執(zhí)行權(quán)限,所以執(zhí)行失敗 root@sparkmaster:~/ShellLearning/chapter09# ./HelloWorld.sh bash: ./HelloWorld.sh: Permission denied root@sparkmaster:~/ShellLearning/chapter09# ls -l total 4 -rw-r--r-- 1 root root 31 2015-09-30 06:29 HelloWorld.sh //chmod給文件加執(zhí)行權(quán)限 root@sparkmaster:~/ShellLearning/chapter09# chmod a+x HelloWorld.sh //再通過(guò)自執(zhí)行方式 root@sparkmaster:~/ShellLearning/chapter09# ./HelloWorld.sh Hello Shell root@sparkmaster:~/ShellLearning/chapter09#
前面提到,腳本第一行是#!/bin/bash,它的作用是提示該腳本的執(zhí)行路徑是/bin/bash,對(duì)自執(zhí)行方式有用,自執(zhí)行方式最終是通過(guò)/bin/bash HelloWorld.sh 執(zhí)行腳本,而利用sh HelloWorld.sh命令執(zhí)行腳本時(shí),#!/bin/bash 不起作用。
HelloWorld.sh文件中的echo “Hello Shell”是一條語(yǔ)句,一般習(xí)慣于一行一條語(yǔ)句,如:
#!/bin/bash echo "Hello Shell" echo "Hello World"
如果要將上述語(yǔ)句放在一行,則需要用;隔開(kāi)
echo "Hello Shell";echo "Hello World"
echo命令用于輸出一行內(nèi)容(包括行符),后面的輸出內(nèi)容除可以用”“雙引號(hào)之外,也可以不加,也可以用單引號(hào)”例如:
root@sparkmaster:~/ShellLearning/chapter09# echo "Hello World" Hello World root@sparkmaster:~/ShellLearning/chapter09# echo Hello World Hello World root@sparkmaster:~/ShellLearning/chapter09# echo 'Hello World' Hello World
這三種方式看上去似乎相同,但其實(shí)它們之間還是有差異的,具體如下:
//對(duì)于一些特殊字符,雙引號(hào)可能不會(huì)正常輸出 root@sparkmaster:~/ShellLearning/chapter09# echo "Hello World!" bash: !": event not found //不帶引號(hào)的參數(shù)不會(huì)出現(xiàn)這種情況 root@sparkmaster:~/ShellLearning/chapter09# echo 'Hello World!' Hello World! //單引號(hào)也能正常輸出 root@sparkmaster:~/ShellLearning/chapter09# echo Hello World! Hello World! //不帶引號(hào)的參數(shù)使用如果帶特殊字符,兩條語(yǔ)句不能放在同一行 root@sparkmaster:~/ShellLearning/chapter09# echo Hello World!;echo Hello bash: !: event not found //不帶引號(hào),輸出的是變量?jī)?nèi)容 root@sparkmaster:~/ShellLearning/chapter09# echo $JAVA_HOME /hadoopLearning/jdk1.7.0_67 //雙引號(hào),輸出的也是變量?jī)?nèi)容 root@sparkmaster:~/ShellLearning/chapter09# echo "$JAVA_HOME" /hadoopLearning/jdk1.7.0_67 //單引號(hào)的話,內(nèi)容原樣輸出,不會(huì)解析變量值 root@sparkmaster:~/ShellLearning/chapter09# echo '$JAVA_HOME' $JAVA_HOME
前一小節(jié)提到$JAVA_HOME,這是配置的JAVA環(huán)境變量,這一小節(jié)我們將介紹如何進(jìn)行變量定義,如何配置環(huán)境變量。同任何的編程語(yǔ)言一樣,變量是用來(lái)存儲(chǔ)可變數(shù)據(jù)的,即在程序運(yùn)行過(guò)程中變量中的數(shù)據(jù)可能隨時(shí)發(fā)生變化。shell腳本中的變量同其它腳本語(yǔ)言一樣,在使用時(shí)不需要進(jìn)行類(lèi)型定義,不管是加引號(hào)還是不加引號(hào)定義變量,其類(lèi)型都為String,例如:
//t1為String類(lèi)型 root@sparkmaster:~/ShellLearning/chapter09# t1="123" root@sparkmaster:~/ShellLearning/chapter09# $t1 123: command not found root@sparkmaster:~/ShellLearning/chapter09# echo $t1 //t1為String類(lèi)型 root@sparkmaster:~/ShellLearning/chapter09# t1=123 root@sparkmaster:~/ShellLearning/chapter09# echo $t1 123
上面的變量是我們自己定義的,它具有一定的局部性,例如:
root@sparkmaster:~/ShellLearning/chapter09# t1=123 //在當(dāng)前進(jìn)程中能夠正常輸出內(nèi)容 root@sparkmaster:~/ShellLearning/chapter09# echo $t1 123 //開(kāi)啟一個(gè)子進(jìn)程 root@sparkmaster:~/ShellLearning/chapter09# bash //無(wú)內(nèi)容輸出 root@sparkmaster:~/ShellLearning/chapter09# echo $t1 //退出,返回原父進(jìn)程 root@sparkmaster:~/ShellLearning/chapter09# exit exit //內(nèi)容又能夠正常輸出 root@sparkmaster:~/ShellLearning/chapter09# echo $t1 123
從上面的代碼可以看到,自定義變量具有只能在當(dāng)前進(jìn)程中使用,當(dāng)開(kāi)啟子進(jìn)程時(shí),變量在子進(jìn)程中不起作用,如果需要父進(jìn)程中定義的變量在子進(jìn)程中也能夠使用,則需要將其設(shè)置為環(huán)境變量,環(huán)境變量使用export命令進(jìn)行定義,代碼如下:
//采用export命令將t1設(shè)置為環(huán)境變量 root@sparkmaster:~/ShellLearning/chapter09# export t1 root@sparkmaster:~/ShellLearning/chapter09# bash //子進(jìn)程中現(xiàn)在可能使用 root@sparkmaster:~/ShellLearning/chapter09# $t1 123: command not found root@sparkmaster:~/ShellLearning/chapter09# echo $t1 123
不過(guò),這樣定義的環(huán)境變量,在命令行窗口關(guān)閉或系統(tǒng)重新啟動(dòng)時(shí)會(huì)丟失,如果需要在機(jī)器啟動(dòng)時(shí)環(huán)境變量就自動(dòng)生效的話,可以將環(huán)境變量定義在~/.bashrc或/etc/profile文件中,其中~/.bashrc只對(duì)當(dāng)前用戶(hù)(例如當(dāng)前用戶(hù)是zhouzhihu,則只對(duì)本用戶(hù)有效),如果想對(duì)所有用戶(hù)都有效,則將其放置在/etc/profile文件中。
下圖給出了java、scala語(yǔ)言等環(huán)境變量配置演示:
在linux腳本編程中,有幾個(gè)非常重要的特殊變量,說(shuō)它特殊是因?yàn)樗兞繜o(wú)需程序員自己定義,系統(tǒng)默認(rèn)會(huì)幫我們進(jìn)行初始化等相關(guān)操作,常用特殊變量如下:
$# 是傳給腳本的參數(shù)個(gè)數(shù) $0 是腳本本身的名字 $1 是傳遞給該shell腳本的第一個(gè)參數(shù) $2 是傳遞給該shell腳本的第二個(gè)參數(shù) $@ 是傳給腳本的所有參數(shù)的列表 $* 是以一個(gè)單字符串顯示所有向腳本傳遞的參數(shù),與位置變量不同,參數(shù)可超過(guò)9個(gè) $$ 是腳本運(yùn)行的當(dāng)前進(jìn)程ID號(hào) $? 是顯示最后命令的退出狀態(tài),0表示沒(méi)有錯(cuò)誤,其他表示有錯(cuò)誤
下面我們舉例進(jìn)行演示:
root@sparkmaster:~/ShellLearning/chapter09# vi SpecialVariable.sh
root@sparkmaster:~/ShellLearning/chapter09# ./SpecialVariable.sh 1 2 3 4
4
./SpecialVariable.sh
1
2
1 2 3 4
1 2 3 4
17138
0
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn