??我們?cè)诘谝淮巫鳛檫\(yùn)維人員去學(xué)習(xí)和寫(xiě)shell腳本的時(shí)候,我們經(jīng)常會(huì)做什么,我們把我們?cè)?? Linux上面去執(zhí)行的那些命令,我們一股腦的全部把它丟到shell腳本里面來(lái)。??
舉個(gè)例子就是說(shuō)我們要做什么,??我們先用 Linux 系統(tǒng)上面,先在 Linux 系統(tǒng)上面先演示,我們先到宿主機(jī)目錄上面,??我們有個(gè)test目錄,我們先把它刪掉,
我們?cè)倏词遣皇菦](méi)有 test目錄了?
假設(shè)我們??登錄到這個(gè)系統(tǒng)上面,我們需要做一系列的步驟,??比如說(shuō)我們第一件事情是什么叫mkdir test , 我們先新建這樣的一個(gè)目錄,然后我們?cè)龠M(jìn)入到?? test目錄里面去對(duì)不對(duì)?然后接著我們 ls 一下,這里什么都沒(méi)有, 最后的話我們?cè)?touch 一個(gè)??比如說(shuō)test點(diǎn)txt文件,我們新建的這樣一個(gè)文件,這個(gè)時(shí)候我們來(lái)看里面有一個(gè)test點(diǎn)txt文件,??然后我們輸入一個(gè)什么hello word是吧?我們輸入這樣的內(nèi)容把它導(dǎo)入到 text點(diǎn)txt文本里面,??接著的話我們?cè)?cat 一下 test點(diǎn)txt,
假設(shè)我們收工了,我們要退出了之后,這個(gè)目錄還在,我們還要做一個(gè)什么事情,我們要把它?? rm -rf test/ ,我們把它刪掉。
假設(shè)我們要在每臺(tái)節(jié)點(diǎn)上面都去這樣子操作一下,七八個(gè)步驟,做起來(lái)還是至少要個(gè)九秒八秒五秒對(duì)吧?假設(shè)我們現(xiàn)在就要寫(xiě)腳本,??在腳本里面能夠?qū)崿F(xiàn)這種自動(dòng)化操作,我們直接運(yùn)行的腳本就把我們剛才的事情都做了,??我們?cè)趺磳?xiě)?
我們首先第一步就是#!/bin/bash,默認(rèn)寫(xiě)在里面, 第一步我們做什么?我們要先跳到宿主機(jī)目錄上面來(lái),對(duì)不對(duì)?我們用 cd ~,這個(gè)~表示宿主機(jī)目錄,如果是對(duì)于 root 用戶的話,它的宿主目錄是什么?是/root目錄。??
如果是其他普通用戶,波浪線~表示的是什么???表示的是/home/用戶名,~ 它其實(shí)是有兩種表示含義,如果說(shuō)你是root的話,波浪線~表示的是/root目錄這個(gè)路徑,?? 如果是其他普通用戶的話,那么這個(gè)波浪線~表示就是/home/用戶名。
我們先進(jìn)到宿主目錄之后,然后我們是不是mkdir test創(chuàng)建了一個(gè)test目錄是吧?接著的話我們是不是要進(jìn)入到 text目錄里面去,cd test
接著我們做了一個(gè)什么事情,我們是不是創(chuàng)建了一個(gè)test點(diǎn)txt文件,touch test.txt然后我們輸出重定向,我們?cè)偻锩鎸?xiě)了一行 hello,world,到text文本里面去,echo "htllo,world" >> test.txt
然后接著我們做了一個(gè)什么事情,cat test.txt, 之后做什么,我們?cè)偬鰜?lái),??跳到上一級(jí)目錄,cd ..
接著我們就 rm -rf test,把整個(gè)目錄移除/刪掉,??
這是我們剛剛做的動(dòng)作,我們把所有的動(dòng)作命令,我們所有執(zhí)行的操作我們?nèi)糠诺竭@來(lái)。??
接著的話我們希望到另外一個(gè)節(jié)點(diǎn),我們做同樣的事情的時(shí)候,我們就只需要執(zhí)行一下這個(gè)腳本, 我們看一下我們這個(gè)代碼有沒(méi)有傳過(guò)來(lái),代碼已經(jīng)全部傳過(guò)來(lái)了,
接著的話我們來(lái)做一個(gè)什么事情,我們要執(zhí)行一下,??
chmod +x second.sh 權(quán)限也一樣,然后./second.sh
執(zhí)行腳本它輸出hello,world, hello,world 是哪里輸出來(lái)的???cat test.txt就輸出了,
但是整個(gè)過(guò)程我們其實(shí)沒(méi)有感知到,我們看到這下面并沒(méi)有 test的目錄創(chuàng)建,
相當(dāng)于我們執(zhí)行這一項(xiàng),??可能不到一秒鐘我們就執(zhí)行了剛才這么多的步驟, 經(jīng)常的我們到一個(gè)系統(tǒng)上面去部署一個(gè)服務(wù)的時(shí)候,??步驟都是一樣的, 比如我們先把原來(lái)的服務(wù)先停掉,然后把原來(lái)的整個(gè)目錄備份,??備份了之后,然后把我們的新包拷到里面去,拷到某個(gè)目錄里面,然后解壓, 然后執(zhí)行里面的啟動(dòng)腳本,這樣子就可以了。??
我們這個(gè)步驟其實(shí)相當(dāng)于就是把運(yùn)維人員里面寫(xiě)的那些腳本一步一步寫(xiě)到這里面來(lái),??這就是一個(gè)命令堆積的過(guò)程。但是這樣的一個(gè)腳本會(huì)不會(huì)有問(wèn)題, 舉個(gè)例子,比如說(shuō)??我們這里是不是兩次出現(xiàn)了text, 我們假設(shè)我們要換一個(gè)目錄,我們要換一個(gè)text1,我們創(chuàng)建一個(gè)tes,1目錄的話,??我們這里是不是要改一下,這里要改一下,還有這里再改一下,我們要改三個(gè)地方, 我們?nèi)绻?a href="http://www.1cnz.cn/v/tag/1315/" target="_blank">編程經(jīng)驗(yàn)的人的話,我們就知道我們說(shuō)把這種共同的東西,我們抽象出來(lái),我們寫(xiě)一個(gè)變量,??比如部署任務(wù)叫DEPLOY_DIR=test, 我們就叫做test,假設(shè)我們這里創(chuàng)建的時(shí)候,這個(gè)時(shí)候我們創(chuàng)建就用變量名用$DEPLOY_DIR去代替,??使用變量的時(shí)候一定要在前面加上多樂(lè)符$, 然后比如說(shuō)我們 cd 也用變量名$DEPLOY_DIR代替,然后最后的rm -rf也把它用$DEPLOY_DIR代替。??
這樣子的話,假設(shè)我要?jiǎng)?chuàng)建一個(gè)test2,我們只要改這里就可以了,這是第一點(diǎn),我們把它這些東西變成了變量。??
創(chuàng)建的文件,假設(shè)我們叫 USE_FILE=text.txt, 我們把我們接下來(lái)會(huì)用到的創(chuàng)建的文件把它改一下,??導(dǎo)入到$USE_FILE里面來(lái), 然后我cat也是這樣 cat $USE_FILE,?? 我們就是用變量實(shí)現(xiàn)了一個(gè)改造,優(yōu)化了一下腳本,??這樣的話如果說(shuō)腳本想要比如說(shuō)我要?jiǎng)?chuàng)建換一個(gè)新的目錄,或者說(shuō)??我導(dǎo)入到不同的文件的時(shí)候, 我們只需要改一處地方就可以了。??這樣的話整個(gè)腳本稍微會(huì)好一點(diǎn),比如說(shuō)免得你變量相同的值到處寫(xiě),??假設(shè)如果說(shuō)是另外一個(gè)人維護(hù)的時(shí)候,我要改一下,可能他只改了一處地方,你還有其他幾處地方?jīng)]有改的話,腳本執(zhí)行就會(huì)有問(wèn)題,??
我們腳本盡量的把一些經(jīng)常用的地方我們要抽成變量,??其他編程語(yǔ)言它都要做的一個(gè)事情,就是不要讓一個(gè)特殊的值在整個(gè)代碼的文件里面到處跑。??
好,這樣子的話,我們接下來(lái)這個(gè)代碼還有沒(méi)有需要改造的,當(dāng)然肯定是有。?? 首先我們??這樣一點(diǎn)我們要注意一下,首先第一個(gè)是我們創(chuàng)建 test目錄,你說(shuō)有沒(méi)有可能會(huì)失敗??? 假如失敗了之后,假設(shè)我們說(shuō)原來(lái)我們有 test目錄對(duì)不對(duì)?我們有 text目錄,我們這里創(chuàng)建失敗了,??你就要記住一點(diǎn),這個(gè)腳本你即使命令執(zhí)行失敗了,它的腳本默認(rèn)會(huì)繼續(xù)執(zhí)行下去了。??假設(shè)這是別人的目錄,??我要?jiǎng)?chuàng)建一個(gè)目錄的時(shí)候,我發(fā)現(xiàn)創(chuàng)建了別人的目錄,??別人的目錄它存在導(dǎo)致我們命令失敗了,但是我們這個(gè)命令并不會(huì)停下來(lái),它會(huì)往下走走走到這里:
它會(huì)把別人的整個(gè)目錄全部給刪掉,??這樣子就會(huì)帶來(lái)一個(gè)什么問(wèn)題。??我把別人的東西給刪掉了,而且是rm -rf,這個(gè)命令也要在生產(chǎn)環(huán)境里面一定要注意,所謂網(wǎng)上調(diào)侃從刪庫(kù)跑路,就是說(shuō)你用的這個(gè)rm -rf / ,/ 就是根目錄。??你把從根目錄開(kāi)始下的所有的文件,假設(shè)你有宿主權(quán)限的話,就一口氣全部給它刪干凈了,??好家伙,這臺(tái)機(jī)器基本上就廢掉了,所以這個(gè)時(shí)候的話不是你被公司開(kāi)除,就是公司要把你給抓到什么監(jiān)獄里面去,??
所以說(shuō)這個(gè)命令很危險(xiǎn),??而且你這樣子假設(shè)即使你這里用了 test是吧,刪的是別人的目錄,??那也可能會(huì)造成一定很大的一個(gè)影響,對(duì)不對(duì)???假設(shè)我就說(shuō)我把這里??改成根目錄或者改成 etc:
這些都是重要配置文件,你刪了之后,??你再重啟一下機(jī)器的時(shí)候,你就發(fā)現(xiàn)它起不起來(lái)了,也就是說(shuō) mkdir創(chuàng)建失敗,它其實(shí)會(huì)造成一個(gè)什么???就是說(shuō)失敗了的話,我希望ta能夠不要執(zhí)行下去。??shell里面會(huì)有這樣的一個(gè)操作,就是 set -e,??set +e表示的是命令遇到錯(cuò)誤會(huì)繼續(xù)執(zhí)行,遇到錯(cuò)誤會(huì)繼續(xù)執(zhí)行,??set -e表示的就是遇到錯(cuò)誤停止運(yùn)行。??
我們可以試一下,
比如說(shuō)我們刪除這個(gè)目錄,我們只是打印提示信息說(shuō)一下,并不真正的做刪除目錄。?? 如果是第一次執(zhí)行了之后,這個(gè)目錄還是存在的。??接著我們?cè)俅螆?zhí)行第二次的時(shí)候,我們注釋一下,
好,我們來(lái)跑一下腳本,??
這個(gè)時(shí)候它輸出了 hello world,同時(shí)刪除這個(gè)目錄,但是這個(gè)目錄是沒(méi)有被刪除的,我們先看一下:
有test目錄對(duì)不對(duì)?它存在??。
接著的話我們?cè)俅螆?zhí)行:
大家看到無(wú)法創(chuàng)建目錄,文件已經(jīng)存在,??我輸出了兩個(gè)hello world,是因?yàn)樵瓉?lái)已經(jīng)追加的一個(gè)hello world在里面,然后又來(lái)一個(gè)hello world,但是我又執(zhí)行了刪除目錄,??也就是說(shuō)我們沒(méi)有默認(rèn)的情況下,命令報(bào)錯(cuò)了,它會(huì)繼續(xù)往下執(zhí)行對(duì)不對(duì)???
假設(shè)我們把第3行注釋取消,我們?cè)倏匆幌拢?/p>
我們?cè)俅螆?zhí)行的時(shí)候,我們可以看到:
mkdir 這里命令報(bào)錯(cuò)了之后,后面的cat什么刪除這些提示信息【刪除test目錄】都沒(méi)有被執(zhí)行了,也就是說(shuō)我們可以通過(guò)??這樣的一個(gè)方式去控制命令,就是遇到錯(cuò)誤之后要不要繼續(xù)執(zhí)行,??我們可以簡(jiǎn)單的這樣設(shè)置一下,這是shell里面的一個(gè)規(guī)范規(guī)則。??
接著的話我們還可以做一個(gè)什么事情??? 比如說(shuō)我們的 test或者文件,我們都可以從外面的去傳,??
代碼:
解讀代碼:假設(shè)我們還可以做一個(gè)什么事情,我們的目錄??我們可以通過(guò)腳本自己傳入,多了符號(hào)$表示從腳本外面?zhèn)鞯?a target="_blank">參數(shù),?? 假設(shè)我們是 -eq 1,?? 然后 我們用一下 if,后面我們會(huì)專門(mén)去介紹這個(gè)if語(yǔ)句的判斷語(yǔ)句怎么用,就是說(shuō)我們腳本如果是傳入了一個(gè),?? 然后我們先給一個(gè)默認(rèn)值,【第5行】
如果說(shuō)我們的參數(shù)傳來(lái)一個(gè)值,??就先把第一個(gè)參數(shù)當(dāng)做是要?jiǎng)?chuàng)建的部署的目錄, 假設(shè)我們傳入了腳本, 假設(shè)第一個(gè)參數(shù)是xx,我們傳了一個(gè)xxx的時(shí)候,它表示了一個(gè)位置參數(shù),它就在多了一的位置上面,??如果有的話,我們就把 xxx 這個(gè)值賦給這個(gè)變量$1,【第9行】
假設(shè)我們這里還有一個(gè)yyy??的話,這就是第二個(gè)參數(shù)。?? 如果說(shuō)是它的參數(shù)的個(gè)數(shù)等于2的話,我們就會(huì)把??第二個(gè)參數(shù)傳給 $2,即USER_FILE變量,【第14行】
我們用 echo 輸出提示信息【第24行】
也就是說(shuō)我們這里是加了兩個(gè)if,可以通過(guò)外部的參數(shù)來(lái)控制這兩個(gè)變量的值。??
大概的邏輯就這些。
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
593瀏覽量
27392 -
Shell
+關(guān)注
關(guān)注
1文章
365瀏覽量
23358 -
root
+關(guān)注
關(guān)注
1文章
86瀏覽量
21389
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論