shell

第 2 章 SHELL 基礎(chǔ)知識(shí)
2.1 shell腳本
我們?cè)谏厦婧?jiǎn)單介紹了一下什么是shell腳本,現(xiàn)在我們來(lái)進(jìn)一步的來(lái)介紹shell腳本的要求/格式/規(guī)范等內(nèi)容
2.1.1 創(chuàng)建腳本
腳本創(chuàng)建工具:
創(chuàng)建腳本的常見(jiàn)編輯器是 vi/vim.

腳本命名
shell腳本的命名簡(jiǎn)單來(lái)說(shuō)就是要有意義,方便我們通過(guò)腳本名,來(lái)知道這個(gè)文件是干什么用的。

腳本內(nèi)容:
各種可以執(zhí)行的命令

注釋內(nèi)容:
單行注釋?zhuān)?br> 除了首行的#不是注釋外,其他所有行內(nèi)容,只要首個(gè)字符是#,那么就表示該行是注釋

!/bin/bash

echo '1'

echo '2' # 這一行就表示注釋

echo '3'

多行注釋?zhuān)?br> 多行注釋有兩種方法::<<! ... ! 和 :<<字符 ... 字符

!/bin/bash

echo '1'
:<<! echo '2'
echo '3'
echo '4'
!
echo '5'

2.1.2 腳本執(zhí)行
shell執(zhí)行的方式
Shell腳本的執(zhí)行通??梢圆捎靡韵聨追N方式

bash /path/to/script-name 或 /bin/bash /path/to/script-name (強(qiáng)烈推薦使用)
/path/to/script-name 或 ./script-name (當(dāng)前路徑下執(zhí)行腳本)
source script-name 或 . script-name (注意“.“點(diǎn)號(hào))

執(zhí)行說(shuō)明:
1、腳本文件本身沒(méi)有可執(zhí)行權(quán)限或者腳本首行沒(méi)有命令解釋器時(shí)使用的方法,我們推薦用bash執(zhí)行。
使用頻率:☆☆☆☆☆
2、腳本文件具有可執(zhí)行權(quán)限時(shí)使用。
使用頻率:☆☆☆☆
3、使用source或者.點(diǎn)號(hào),加載shell腳本文件內(nèi)容,使shell腳本內(nèi)容環(huán)境和當(dāng)前用戶(hù)環(huán)境一致。
使用頻率:☆☆☆
使用場(chǎng)景:環(huán)境一致性
2.1.2 腳本開(kāi)發(fā)規(guī)范
1、腳本命名要有意義,文件后綴是.sh
2、腳本文件首行是而且必須是腳本解釋器

!/bin/bash

3、腳本文件解釋器后面要有腳本的基本信息等內(nèi)容
腳本文件中盡量不用中文注釋;
盡量用英文注釋?zhuān)乐贡緳C(jī)或切換系統(tǒng)環(huán)境后中文亂碼的困擾
常見(jiàn)的注釋信息:腳本名稱(chēng)、腳本功能描述、腳本版本、腳本作者、聯(lián)系方式等
4、腳本文件常見(jiàn)執(zhí)行方式:bash 腳本名
5、腳本內(nèi)容執(zhí)行:從上到下,依次執(zhí)行
6、代碼書(shū)寫(xiě)優(yōu)秀習(xí)慣;
1)成對(duì)內(nèi)容的一次性寫(xiě)出來(lái),防止遺漏。
如:()、{}、[]、''、``、""
2)[]中括號(hào)兩端要有空格,書(shū)寫(xiě)時(shí)即可留出空格[ ],然后再退格書(shū)寫(xiě)內(nèi)容。
3)流程控制語(yǔ)句一次性書(shū)寫(xiě)完,再添加內(nèi)容
7、通過(guò)縮進(jìn)讓代碼易讀;(即該有空格的地方就要有空格)


2.2 變量
變量的學(xué)習(xí)我們主要從四個(gè)方面來(lái)學(xué)習(xí):
變量的定義和分類(lèi)
本地變量
全局變量
shell內(nèi)置變量
2.2.1 什么是變量
變量是什么?
變量包括兩部分:
變量名 不變的
變量值 變化的
我們一般所說(shuō)的變量指的是:變量名
2.2.2 本地變量
本地變量是什么?
本地變量就是:在當(dāng)前系統(tǒng)的某個(gè)環(huán)境下才能生效的變量,作用范圍小。
本地變量包含兩種:普通變量和命令變量

普通變量:
普通變量的定義方式有如下三種,接下來(lái)我們就分別說(shuō)一下這三種方式:

方式一:
變量名=變量值
重點(diǎn):
變量值必須是一個(gè)整體,中間沒(méi)有特殊字符
方式二:
變量名='變量值'
重點(diǎn):
我看到的內(nèi)容,我就輸出什么內(nèi)容
方式三:
變量名="變量值"
重點(diǎn):
如果變量值范圍內(nèi),有可以解析的變量A,那么首先解析變量A,將A的結(jié)果和其他內(nèi)容組合成一個(gè)整體,重新賦值給變量B

習(xí)慣:
數(shù)字不加引號(hào),其他默認(rèn)加雙引號(hào)

命令變量(熟練)
命令變量有兩種定義方式,接下來(lái)我們就來(lái)介紹一下這兩種方式

定義方式一:
變量名=命令
注意:
` 是反引號(hào)

定義方式二:
變量名=$(命令)

執(zhí)行流程:
1、執(zhí)行`或者$()范圍內(nèi)的命令
2、將命令執(zhí)行后的結(jié)果,賦值給新的變量名A


2.2.3 全局變量
全局變量是什么
全局變量就是:在當(dāng)前系統(tǒng)的所有環(huán)境下都能生效的變量。

查看全局變量命令
可以通過(guò)命令查看環(huán)境變量
env 只顯示全局變量

定義全局變量
方法一:
變量=值
export 變量
方法二:(最常用)
export 變量=值

2.2.4 變量查看和取消
查看變量:
方式一:
變量名 場(chǎng)景: 私下里,在命令行/腳本中使用 圖省事 方式二: "變量名"
場(chǎng)景:
私下里,在命令行/腳本中使用
圖省事
方式三:
{變量名} 場(chǎng)景: echo " dsa dsafsa dsafsa{變量名} f "
使用頻率較高
方式四:
"${變量名}"
場(chǎng)景:
標(biāo)準(zhǔn)使用方式

取消變量
unset 變量名


2.2.5 shell內(nèi)置變量
我們之前學(xué)習(xí)的本地變量,全局變量都是需要通過(guò)定義,然后才能實(shí)現(xiàn)相應(yīng)功能的,那么有沒(méi)有一些變量我們可以直接拿過(guò)來(lái)使用實(shí)現(xiàn)某種具體的功能呢?有,這就是shell內(nèi)置變量
和腳本文件有關(guān)
符號(hào) 意義
0 獲取當(dāng)前執(zhí)行的shell腳本文件名,包括腳本路徑n 獲取當(dāng)前執(zhí)行的shell腳本的第n個(gè)參數(shù)值,n=1..9,當(dāng)n為0時(shí)表示腳本的文件名,如果n大于9就要用大 括號(hào)括起來(lái){10}# 獲取當(dāng)前shell命令行中參數(shù)的總個(gè)數(shù)
$? 獲取執(zhí)行上一個(gè)指令的返回值(0為成功,非0為失?。?/p>

重點(diǎn)內(nèi)置變量演示效果:
$0 獲取腳本的名稱(chēng)
示例:

!/bin/bash

獲取腳本的名稱(chēng)

echo "我腳本的名稱(chēng)是: file.sh"
echo "我腳本的名稱(chēng)是:$0"

# 獲取當(dāng)前腳本傳入?yún)?shù)的數(shù)量n 獲取當(dāng)前腳本傳入的第n個(gè)位置的參數(shù)
示例:

!/bin/bash

獲取當(dāng)前腳本傳入的參數(shù)數(shù)量

echo "當(dāng)前腳本傳入的參數(shù)數(shù)量是: $#"

獲取指定位置的參數(shù)

echo "第一個(gè)位置的參數(shù)是: 1" echo "第二個(gè)位置的參數(shù)是:2"
echo "第三個(gè)位置的參數(shù)是: 3" echo "第四個(gè)位置的參數(shù)是:4"

$? 獲取文件執(zhí)行或者命令執(zhí)行的返回狀態(tài)值
示例:

bash nihao

bash: nihao: No such file or directory

echo $?

127

ls

file1.sh num.sh test.sh weizhi.sh

echo $?

0

字符串精確截取
格式:${變量名:起始位置:截取長(zhǎng)度}

示例:
{file:0:5} 從第1個(gè)字符開(kāi)始,截取5個(gè)字符{file::5} 從第1個(gè)字符開(kāi)始,截取5個(gè)字符
{file:5:5} 從第6個(gè)字符開(kāi)始,截取5個(gè)字符{file:5} 從第6個(gè)字符開(kāi)始,截取后面所有的字符
{file:0-5} 從倒數(shù)第5個(gè)字符開(kāi)始,截取后面所有的字符{file:0-6:3} 從倒數(shù)第6個(gè)字符開(kāi)始,截取之后的3個(gè)字符

默認(rèn)值相關(guān)
場(chǎng)景一:
變量a如果有內(nèi)容,那么就輸出a的變量值
變量a如果沒(méi)有內(nèi)容,那么就輸出默認(rèn)的內(nèi)容

格式:
    ${變量名:-默認(rèn)值}

套餐示例:
    如果我輸入的參數(shù)為空,那么輸出內(nèi)容是 "您選擇的套餐是: 套餐 1"
    如果我輸入的參數(shù)為n,那么輸出內(nèi)容是 "您選擇的套餐是: 套餐 n"  

!/bin/bash

套餐選擇演示

a="1" echo "您選擇的套餐是: 套餐{a:-1}"

場(chǎng)景二:
無(wú)論變量a是否有內(nèi)容,都輸出默認(rèn)值
格式:
${變量名+默認(rèn)值}
場(chǎng)景示例:
不管我說(shuō)國(guó)家法定結(jié)婚年齡是 多少歲,都輸出 國(guó)家法定結(jié)婚年齡(男性)是 22 歲

!/bin/bash

默認(rèn)值演示示例二

a="1" echo "國(guó)家法定結(jié)婚年齡(男性)是{a+22} 歲"


第 3 章 SHELL 進(jìn)階
這部分的知識(shí),我們主要是從三個(gè)方面來(lái)學(xué)習(xí):
測(cè)試語(yǔ)句
表達(dá)式(條件+計(jì)算)
linux常見(jiàn)符號(hào)和命令
3.1 表達(dá)式
要使Shell腳本程序具備一定的“邏輯能力”,面臨的第一個(gè)問(wèn)題就是:區(qū)分不同的情況以確定執(zhí)行何種操作,下面我們就來(lái)學(xué)習(xí)解決這個(gè)問(wèn)題---測(cè)試語(yǔ)句
3.1.1 測(cè)試語(yǔ)句
Shell環(huán)境根據(jù)命令執(zhí)行后的返回狀態(tài)值($?)來(lái)判斷是否執(zhí)行成功,當(dāng)返回值為0,表示成功,值為其他時(shí),表示失敗。使用專(zhuān)門(mén)的測(cè)試工具---test命令,可以對(duì)特定條件進(jìn)行測(cè)試,并根據(jù)返回值來(lái)判斷條件是否成立(返回值0為成立)

測(cè)試語(yǔ)句形式
A: test 條件表達(dá)式
B: [ 條件表達(dá)式 ]
格式注意:
以上兩種方法的作用完全一樣,后者為常用。
但后者需要注意方括號(hào)[、]與條件表達(dá)式之間至少有一個(gè)空格。
test跟 [] 的意思一樣
條件成立,狀態(tài)返回值是0
條件不成立,狀態(tài)返回值是1

操作注意:
[]兩側(cè)為什么要有空格
root@ubuntu:~# [-x /bin/bash ]
[-x: command not found
可以看到:
兩側(cè)沒(méi)有空格,就會(huì)報(bào)錯(cuò),為什么呢?因?yàn)槟悴缓弦?guī)范

3.1.2 條件表達(dá)式
我們這部分內(nèi)容主要是介紹,測(cè)試語(yǔ)句中的 [ 條件表達(dá)式 ] 這一部分,測(cè)試的結(jié)果使用 echo $? 來(lái)查看

邏輯表達(dá)式
邏輯表達(dá)式一般用于判斷多個(gè)條件之間的依賴(lài)關(guān)系。
常見(jiàn)的邏輯表達(dá)式有: && 和 ||

&&
命令1 && 命令2
如果命令1執(zhí)行成功,那么我才執(zhí)行命令2 -- 夫唱婦隨
如果命令1執(zhí)行失敗,那么命令2也不執(zhí)行
示例:

[ 1 = 1 ] && echo "條件成立"

條件成立

[ 1 = 2 ] && echo "條件成立"

||
命令1 || 命令2
如果命令1執(zhí)行成功,那么命令2不執(zhí)行 -- 對(duì)著干
如果命令1執(zhí)行失敗,那么命令2執(zhí)行
示例:

[ 1 = 2 ] || echo "條件不成立"

條件不成立

[ 1 = 1 ] || echo "條件不成立"

文件表達(dá)式

-f 判斷輸入內(nèi)容是否是一個(gè)文件
示例:

[ -f weizhi.sh ] && echo "是一個(gè)文件"

是一個(gè)文件

[ -f weizhi.sddh ] || echo "不是一個(gè)文件"

不是一個(gè)文件

-d 判斷輸入內(nèi)容是否是一個(gè)目錄
示例:

[ -d weizhi.sddh ] || echo "不是一個(gè)目錄"

不是一個(gè)目錄

mkdir nihao

[ -d nihao ] && echo "是一個(gè)目錄"

是一個(gè)目錄

-x 判斷輸入內(nèi)容是否可執(zhí)行
示例:

[ -x age.sh ] || echo "文件沒(méi)有執(zhí)行權(quán)限"

文件沒(méi)有執(zhí)行權(quán)限

[ -x test.sh ] && echo "文件有執(zhí)行權(quán)限"

文件有執(zhí)行權(quán)限

數(shù)值操作符

主要根據(jù)給定的兩個(gè)值,判斷第一個(gè)與第二個(gè)數(shù)的關(guān)系,如是否大于、小于、等于第二個(gè)數(shù)。常見(jiàn)選項(xiàng)如下:
n1 -eq n2 相等
n1 -gt n2 大于
n1 -lt n2 小于
n1 -ne n2 不等于

字符串比較

str1 == str2 str1和str2字符串內(nèi)容一致
str1 != str2 str1和str2字符串內(nèi)容不一致,!表示相反的意思
實(shí)踐
判斷字符是否內(nèi)容一致
root@ubuntu:~# [ a == a ]
root@ubuntu:~# echo ? 0 root@ubuntu:~# [ a != a ] root@ubuntu:~# echo?
1


3.1.3 計(jì)算表達(dá)式
定義:
計(jì)算表達(dá)式,簡(jiǎn)單來(lái)說(shuō)就是對(duì)具體的內(nèi)容進(jìn)行算數(shù)計(jì)算

格式:
方式一:
(())(( 計(jì)算表達(dá)式 ))
方式二:
let let 計(jì)算表達(dá)式

注意:
$(())中只能用+-*/和()運(yùn)算符,并且只能做整數(shù)運(yùn)算

(())演示效果 格式:a=((變量名a+1))
注意:
表達(dá)式范圍內(nèi),空格不限制
計(jì)算示例
root@ubuntu:~# echo $((100/5))
20

let演示效果
格式:let 變量名a=變量名a+1
注意:
表達(dá)式必須是一個(gè)整體,中間不能出現(xiàn)空格等特殊字符
let示例
root@ubuntu:~# i=1
root@ubuntu:~# let i=i+7
root@ubuntu:~# echo $i
8
3.2 linux常見(jiàn)符號(hào)
接下來(lái)我們來(lái)介紹幾個(gè)linux的場(chǎng)景符號(hào):
重定向符號(hào)、管道符、其他符號(hào)
3.2.1 重定向符號(hào)
在shell腳本中有兩種常見(jiàn)的重定向符號(hào) > 和 >>

符號(hào)
作用:
表示將符號(hào)左側(cè)的內(nèi)容,以覆蓋的方式輸入到右側(cè)文件中
演示:
查看文件內(nèi)容
admin-1@ubuntu:~cat file.txt nihao 使用重定向符號(hào)給文件中增加內(nèi)容 admin-1@ubuntu:~ echo "file1.txt" > file.txt
再次查看文件內(nèi)容
admin-1@ubuntu:~$ cat file.txt
file1.txt

符號(hào)
作用:
表示將符號(hào)左側(cè)的內(nèi)容,以追加的方式輸入到右側(cè)文件的末尾行中
演示:
查看文件內(nèi)容
admin-1@ubuntu:~cat file.txt file1.txt 使用重定向符號(hào)給文件中增加內(nèi)容 admin-1@ubuntu:~ echo "file2.txt" >> file.txt
再次查看文件內(nèi)容
admin-1@ubuntu:~$ cat file.txt
file1.txt
file2.txt

3.2.2 管道符 |
定義:
| 這個(gè)就是管道符,傳遞信息使用的

使用格式:
命令1 | 命令2
管道符左側(cè)命令1 執(zhí)行后的結(jié)果,傳遞給管道符右側(cè)的命令2使用

命令演示:
查看當(dāng)前系統(tǒng)中的全局變量SHELL
admin-1@ubuntu:~$ env | grep SHELL
SHELL=/bin/bash

3.2.3 其他符號(hào)
后臺(tái)展示符號(hào) &
定義:
& 就是將一個(gè)命令從前臺(tái)轉(zhuǎn)到后臺(tái)執(zhí)行
使用格式:
命令 &
命令演示:
admin-1@ubuntu:~# sleep 4
界面卡住4秒后消失
admin-1@ubuntu:~# sleep 10 &
[1] 4198
admin-1@ubuntu:~# ps aux | grep sleep
root 4198 0.0 0.0 9032 808 pts/17 S 21:58 0:00 sleep 10
root 4200 0.0 0.0 15964 944 pts/17 S+ 21:58 0:00 grep --color=auto sleep

全部信息符號(hào) 2>&1
符號(hào)詳解:
1 表示正確輸出的信息
2 表示錯(cuò)誤輸出的信息
2>&1 代表所有輸出的信息
符號(hào)示例
標(biāo)準(zhǔn)正確輸出示例
cat nihao.txt 1>> zhengque
標(biāo)準(zhǔn)錯(cuò)誤輸出示例
dsfadsfadsfa 2>> errfile

綜合演練示例
腳本內(nèi)容

!/bin/bash

echo '下一條錯(cuò)誤命令'
dsfsafsafdsa
腳本執(zhí)行效果
admin-1@ubuntu:~# bash ceshi.sh
下一條錯(cuò)誤命令
ceshi.sh: line 3: dsfsafsafdsa: command not found
1 和 2 綜合演練
admin-1@ubuntu:~# bash ceshi.sh 1>> ceshi-ok 2>> ceshi-err
admin-1@ubuntu:~# cat ceshi-ok
下一條錯(cuò)誤命令
admin-1@ubuntu:~# cat ceshi-err
ceshi.sh: line 3: dsfsafsafdsa: command not found
全部信息演練
admin-1@ubuntu:~# bash ceshi.sh >> ceshi-all 2>&1
admin-1@ubuntu:~# cat ceshi-all
下一條錯(cuò)誤命令
ceshi.sh: line 3: dsfsafsafdsa: command not found

linux系統(tǒng)垃圾桶
/dev/null 是linux下的一個(gè)設(shè)備文件,
這個(gè)文件類(lèi)似于一個(gè)垃圾桶,特點(diǎn)是:容量無(wú)限大

3.3 常見(jiàn)命令詳解
接下來(lái)我們介紹一些shell腳本中經(jīng)常使用的linux命令:grep、sed、awk、find
3.3.1 grep命令詳解
grep命令是我們常用的一個(gè)強(qiáng)大的文本搜索命令。
命令格式詳解
grep [參數(shù)] [關(guān)鍵字] <文件名>
注意:
我們?cè)诓榭茨硞€(gè)文件的內(nèi)容的時(shí)候,是需要有<文件名>
grep命令在結(jié)合|(管道符)使用的情況下,后面的<文件名>是沒(méi)有的
可以通過(guò) grep --help 查看grep的幫助信息
參數(shù)詳解
-c:只輸出匹配行的計(jì)數(shù)。
-n:顯示匹配行及行號(hào)。
-v:顯示不包含匹配文本的所有行。

模板文件
admin-1@ubuntu:~cat find.txt nihao aaa nihao AAA NiHao bbb nihao CCC -c: 輸出匹配到aaa的個(gè)數(shù) admin-1@ubuntu:~ grep -c aaa find.txt
1
-n: 輸出匹配內(nèi)容,同時(shí)顯示行號(hào)
admin-1@ubuntu:~grep -n CCC find.txt 4:nihao CCC -v: 匹配到的內(nèi)容部輸出,輸出不匹配的內(nèi)容 admin-1@ubuntu:~ grep -v ni find.txt
NiHao bbb
小技巧:
精確定位錯(cuò)誤代碼
grep -nr [錯(cuò)誤關(guān)鍵字] *


3.3.2 sed命令詳解
sed 行文件編輯工具。因?yàn)樗庉嬑募且孕袨閱挝坏摹?br> 命令格式詳解

命令格式:
sed [參數(shù)] '<匹配條件> [動(dòng)作]' [文件名]
注意:
可以通過(guò) sed --help 查看grep的幫助信息
參數(shù)詳解:
參數(shù)為空 表示sed的操作效果,實(shí)際上不對(duì)文件進(jìn)行編輯
-i 表示對(duì)文件進(jìn)行編輯
注意:mac版本的bash中使用 -i參數(shù),必須在后面單獨(dú)加個(gè)東西: -i ''

匹配條件:
匹配條件分為兩種:數(shù)字行號(hào)或者關(guān)鍵字匹配
關(guān)鍵字匹配格式:
'/關(guān)鍵字/'
注意:
隔離符號(hào) / 可以更換成 @、#、!等符號(hào)
根據(jù)情況使用,如果關(guān)鍵字和隔離符號(hào)有沖突,就更換成其他的符號(hào)即可。

動(dòng)作詳解
-a 在匹配到的內(nèi)容下一行增加內(nèi)容
-i 在匹配到的內(nèi)容上一行增加內(nèi)容
-d 刪除匹配到的內(nèi)容
-s 替換匹配到的內(nèi)容
注意:
上面的動(dòng)作應(yīng)該在參數(shù)為-i的時(shí)候使用,不然的話(huà)不會(huì)有效果
替換命令演示
關(guān)于替換,我們從三個(gè)方面來(lái)學(xué)習(xí):
行號(hào)、列號(hào)、全體
命令格式:
sed -i [替換格式] [文件名]
注意:替換命令的寫(xiě)法
's###' ---> 's#原內(nèi)容##' ---> 's#原內(nèi)容#替換后內(nèi)容#'

常見(jiàn)替換格式:
模板文件內(nèi)容
admin-1@ubuntu:~$ cat sed.txt
nihao sed sed sed
nihao sed sed sed
nihao sed sed sed

替換每行首個(gè)匹配內(nèi)容:
sed -i 's#原內(nèi)容#替換后內(nèi)容#' 文件名

示例:替換首每行的第1個(gè)sed為SED
admin-1@ubuntu:~sed -i 's#sed#SED#' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED sed sed
nihao SED sed sed
nihao SED sed sed

替換全部匹配內(nèi)容:
sed -i 's#原內(nèi)容#替換后內(nèi)容#g' 文件名

示例:替換全部sed為des
admin-1@ubuntu:~sed -i 's#sed#SED#g' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED SED SED
nihao SED SED SED
nihao SED SED SED

指定行號(hào)替換首個(gè)匹配內(nèi)容:
sed -i '行號(hào)s#原內(nèi)容#替換后內(nèi)容#' 文件名

示例:替換第2行的首個(gè)SED為sed
admin-1@ubuntu:~sed -i '2s#SED#sed#' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED SED SED
nihao sed SED SED
nihao SED SED SED

首行指定列號(hào)替換匹配內(nèi)容:
sed -i 's#原內(nèi)容#替換后內(nèi)容#列號(hào)' 文件名

示例:替換每行的第2個(gè)SED為sed
admin-1@ubuntu:~sed -i 's#SED#sed#2' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED sed SED
nihao sed SED sed
nihao SED sed SED

指定行號(hào)列號(hào)匹配內(nèi)容:
sed -i '行號(hào)s#原內(nèi)容#替換后內(nèi)容#列號(hào)' 文件名

示例:替換第3行的第2個(gè)SED為sed
admin-1@ubuntu:~sed -i '3s#SED#sed#2' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED sed SED
nihao sed SED sed
nihao SED sed sed

增加操作

作用:
在指定行號(hào)的下一行增加內(nèi)容
格式:
sed -i '行號(hào)a\增加的內(nèi)容' 文件名
注意:
如果增加多行,可以在行號(hào)位置寫(xiě)個(gè)范圍值,彼此間使用逗號(hào)隔開(kāi),例如
sed -i '1,3a\增加內(nèi)容' 文件名

演示效果:
指定行號(hào)增加內(nèi)容
admin-1@ubuntu:~sed -i '2a\zengjia-2' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED sed SED
nihao sed SED sed
zengjia-2
nihao SED sed sed
指定1~3每行都增加內(nèi)容
admin-1@ubuntu:~sed -i '1,3a\tongshi-2' sed.txt admin-1@ubuntu:~ cat sed.txt
nihao SED sed SED
tongshi-2
nihao sed SED sed
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed

作用:
在指定行號(hào)的當(dāng)行增加內(nèi)容
格式:
sed -i '行號(hào)i\增加的內(nèi)容' 文件名
注意:
如果增加多行,可以在行號(hào)位置寫(xiě)個(gè)范圍值,彼此間使用逗號(hào)隔開(kāi),例如
sed -i '1,3a\增加內(nèi)容' 文件名

演示效果:
指定行號(hào)增加內(nèi)容
admin-1@ubuntu:~sed -i '1i\insert-1' sed.txt admin-1@ubuntu:~ cat sed.txt
insert-1
nihao SED sed SED
tongshi-2
nihao sed SED sed
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed

刪除操作

作用:
指定行號(hào)刪除
格式:
sed -i '行號(hào)d' 文件名
注意:
如果刪除多行,可以在行號(hào)位置多寫(xiě)幾個(gè)行號(hào),彼此間使用逗號(hào)隔開(kāi),例如
sed -i '1,3d' 文件名

刪除演練
刪除第4行內(nèi)容
admin-1@ubuntu:~sed -i '4d' sed.txt admin-1@ubuntu:~ cat sed.txt
insert-1
nihao SED sed SED
tongshi-2
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed

刪除多行(3-5行)內(nèi)容
admin-1@ubuntu:~sed -i '3,5d' sed.txt admin-1@ubuntu:~ cat sed.txt
insert-1
nihao SED sed SED
tongshi-2
nihao SED sed sed


3.3.3 awk命令詳解
awk是一個(gè)功能非常強(qiáng)大的文檔編輯工具,它不僅能以行為單位還能以列為單位處理文件。
命令格式:
awk [參數(shù)] '[ 動(dòng)作]' [文件名]

常見(jiàn)參數(shù):
-F 指定行的分隔符

常見(jiàn)動(dòng)作:
print 顯示內(nèi)容
0 顯示當(dāng)前行所有內(nèi)容n 顯示當(dāng)前行的第n列內(nèi)容,如果存在多個(gè)$n,它們之間使用逗號(hào)(,)隔開(kāi)

常見(jiàn)內(nèi)置變量
FILENAME 當(dāng)前輸入文件的文件名,該變量是只讀的
NR 指定顯示行的行號(hào)
NF 輸出 最后一列的內(nèi)容
OFS 輸出格式的列分隔符,缺省是空格
FS 輸入文件的列分融符,缺省是連續(xù)的空格和Tab

命令演示
模板文件內(nèi)容
admin-1@ubuntu:~$ cat awk.txt
nihao awk awk awk
nihao awk awk awk

打印指定列內(nèi)容
打印第1列的內(nèi)容
admin-1@ubuntu:~awk '{print1}' awk.txt
nihao
nihao

指定行打印內(nèi)容
打印第一行第1和第3列內(nèi)容
admin-1@ubuntu:~awk 'NR==1 {print1,$3}' awk.txt
nihao awk

指定隔離分隔符,查看內(nèi)容
admin-1@ubuntu:~cat linshi.txt root:x:0:0:root:/root:/bin/bash admin-1@ubuntu:~ awk -F ':' '{print 1,7}' linshi.txt
root /bin/bash

設(shè)置顯示分隔符,顯示內(nèi)容
admin-1@ubuntu:~awk 'BEGIN{OFS=":"} {print NR,0}' awk.txt
1:nihao awk awk awk
2:nihao awk awk awk
3.3.4 find命令詳解
命令格式:
find [路徑] [參數(shù)] [關(guān)鍵字]
參數(shù)詳解
-name 按照文件名查找文件。
-perm 按照文件權(quán)限來(lái)查找文件。
-user 按照文件屬主來(lái)查找文件。
-group 按照文件所屬的組來(lái)查找文件。
-type 查找某一類(lèi)型的文件,
諸如:
b - 塊設(shè)備文件 d - 目錄 c - 字符設(shè)備文件
p - 管道文件 l - 符號(hào)鏈接文件 f - 普通文件。
-size n:[c] 查找文件長(zhǎng)度為n塊的文件,帶有c時(shí)表示文件長(zhǎng)度以字節(jié)計(jì)。
-depth:在查找文件時(shí),首先查找當(dāng)前目錄中的文件,然后再在其子目錄中查找。
-mindepth n:在查找文件時(shí),查找當(dāng)前目錄中的第n層目錄的文件,然后再在其子目錄中查找。
! : 表示取反

命令演示
在當(dāng)前系統(tǒng)中查找一個(gè)叫awk的文件
admin-1@ubuntu:~sudo find /home/admin-1/ -name "awk.txt" /home/admin-1/awk.txt 在當(dāng)前系統(tǒng)中查找文件類(lèi)型為普通文件的文件 admin-1@ubuntu:~ find /tmp -type f
/tmp/.X0-lock
/tmp/vgauthsvclog.txt.0
/tmp/unity_support_test.0
/tmp/config-err-4igbXW


第4章 流程控制
在shell的語(yǔ)句中,流程控制主要分為兩種:
簡(jiǎn)單流程控制語(yǔ)句:選擇和循環(huán)
復(fù)雜流程控制語(yǔ)句:函數(shù)
4.1 簡(jiǎn)單流程控制語(yǔ)句
4.1.1 單分支if語(yǔ)句
語(yǔ)法格式
if [ 條件 ]
then
指令
fi

場(chǎng)景:
單一條件,只有一個(gè)輸出

單分支if語(yǔ)句示例

!/bin/bash

單if語(yǔ)句的使用場(chǎng)景

if [ "$1" == "nan" ]
then
echo "您的性別是 男"
fi

4.1.2 雙分支if語(yǔ)句
語(yǔ)法格式
if [ 條件 ]
then
指令1
else
指令2
fi
場(chǎng)景:
一個(gè)條件,兩種結(jié)果

雙分支if語(yǔ)句示例

!/bin/bash

單if語(yǔ)句的使用場(chǎng)景

if [ "$1" == "nan" ]
then
echo "您的性別是 男"
else
echo "您的性別是 女"
fi
4.1.3 多分支if語(yǔ)句
語(yǔ)法格式
if [ 條件 ]
then
指令1
elif [ 條件2 ]
then
指令2
else
指令3
fi
場(chǎng)景:
n個(gè)條件,n+1個(gè)結(jié)果

多分支if語(yǔ)句示例

!/bin/bash

單if語(yǔ)句的使用場(chǎng)景

if [ "1" == "nan" ] then echo "您的性別是 男" elif [ "1" == "nv" ]
then
echo "您的性別是 女"
else
echo "您的性別,我不知道"
fi


多if語(yǔ)句生產(chǎn)場(chǎng)景: 服務(wù)的啟動(dòng)
需求:
要求腳本執(zhí)行需要有參數(shù),通過(guò)傳入?yún)?shù)來(lái)實(shí)現(xiàn)不同的功能。

參數(shù)和功能詳情如下:
參數(shù) 執(zhí)行效果
start 服務(wù)啟動(dòng)中...
stop 服務(wù)關(guān)閉中...
restart 服務(wù)重啟中...
* 腳本 X.sh 使用方式 X.sh [ start|stop|restart ]

腳本內(nèi)容
admin-1@ubuntu:/data/scripts/python-n# cat if.sh

!/bin/bash

多if語(yǔ)句的使用場(chǎng)景

if [ "1" == "start" ] then echo "服務(wù)啟動(dòng)中..." elif [ "1" == "stop" ]
then
echo "服務(wù)關(guān)閉中..."
elif [ "1" == "restart" ] then echo "服務(wù)重啟中..." else echo "0 腳本的使用方式: $0 [ start | stop | restart ]"
fi

4.1.4 case選擇語(yǔ)句
我們發(fā)現(xiàn)多if語(yǔ)句使用的時(shí)候,代碼量很多,而且整體看起來(lái)確實(shí)有那么一丁點(diǎn)亂,有沒(méi)有辦法更好的實(shí)現(xiàn)這種效果呢?就是Case語(yǔ)句。

case 語(yǔ)句格式
case 變量名 in
值1)
指令1
;;
值2)
指令2
;;
值3)
指令3
;;
esac
注意:
首行關(guān)鍵字是case,末行關(guān)鍵字esac
選擇項(xiàng)后面都有 )
每個(gè)選擇的執(zhí)行語(yǔ)句結(jié)尾都有兩個(gè)分號(hào);

case語(yǔ)句示例
場(chǎng)景:在多if語(yǔ)句的基礎(chǔ)上對(duì)腳本進(jìn)行升級(jí)
需求:
要求腳本執(zhí)行需要有參數(shù),通過(guò)傳入?yún)?shù)來(lái)實(shí)現(xiàn)不同的功能。

參數(shù)和功能詳情如下:
參數(shù) 執(zhí)行效果
start 服務(wù)啟動(dòng)中...
stop 服務(wù)關(guān)閉中...
restart 服務(wù)重啟中...
* 腳本 X.sh 使用方式 X.sh [ start|stop|restart ]

腳本內(nèi)容:

cat case.sh

!/bin/bash

case語(yǔ)句使用場(chǎng)景

case "1" in "start") echo "服務(wù)啟動(dòng)中..." ;; "stop") echo "服務(wù)關(guān)閉中..." ;; "restart") echo "服務(wù)重啟中..." ;; *) echo "0 腳本的使用方式: $0 [ start | stop | restart ]"
;;
esac


4.1.5 for循環(huán)語(yǔ)句
循環(huán)指定的所有元素,循環(huán)完畢之后就推出
語(yǔ)法格式
語(yǔ)法格式
for 值 in 列表
do
執(zhí)行語(yǔ)句
done

場(chǎng)景:
遍歷列表

注意:
”for” 循環(huán)總是接收 “in” 語(yǔ)句之后的某種類(lèi)型的字列表
執(zhí)行次數(shù)和list列表中常數(shù)或字符串的個(gè)數(shù)相同,當(dāng)循環(huán)的數(shù)量足夠了,就自動(dòng)退出

示例:遍歷文件

!/bin/bash

for語(yǔ)句的使用示例

for i in (ls /root) do echo "{i}"
done

4.1.6 while循環(huán)語(yǔ)句
語(yǔ)法格式
while 條件
do
執(zhí)行語(yǔ)句
done
注意:
條件的類(lèi)型:
命令、[[ 字符串表達(dá)式 ]]、(( 數(shù)字表達(dá)式 ))

場(chǎng)景:
只要條件滿(mǎn)足,就一直循環(huán)下去

while語(yǔ)句示例
腳本內(nèi)容

!/bin/bash

while的示例

a=1
while [ "{a}" -lt 5 ] do echo "{a}"
a=$((a+1))
done

4.1.7 until循環(huán)語(yǔ)句
語(yǔ)法格式
until 條件
do
執(zhí)行語(yǔ)句
done
注意:
條件的類(lèi)型:
命令、[[ 字符串表達(dá)式 ]]、(( 數(shù)字表達(dá)式 ))

場(chǎng)景:
只要條件不滿(mǎn)足,就一直循環(huán)下去

until語(yǔ)句示例
腳本內(nèi)容

!/bin/bash

until的示例

a=1
until [ "{a}" -eq 5 ] do echo "{a}"
a=$((a+1))
done


4.2 復(fù)雜流程控制語(yǔ)句
函數(shù)就是我們的復(fù)雜流程控制語(yǔ)句
4.2.1 函數(shù)基礎(chǔ)知識(shí)
函數(shù)是什么?
函數(shù)就是將某些命令組合起來(lái)實(shí)現(xiàn)某一特殊功能的方式,是腳本編寫(xiě)中非常重要的一部分。
簡(jiǎn)單函數(shù)格式:
定義函數(shù):
函數(shù)名(){
函數(shù)體
}
調(diào)用函數(shù):
函數(shù)名

傳參函數(shù)格式:
傳參數(shù)
函數(shù)名 參數(shù)
函數(shù)體調(diào)用參數(shù):
函數(shù)名(){
函數(shù)體 $n
}
注意:
類(lèi)似于shell內(nèi)置變量中的位置參數(shù)
4.2.2 函數(shù)實(shí)踐
簡(jiǎn)單函數(shù)定義和調(diào)用示例

!/bin/bash

函數(shù)使用場(chǎng)景一:執(zhí)行頻繁的命令

dayin(){
echo "wo de mingzi shi 111"
}
dayin

函數(shù)傳參和函數(shù)體內(nèi)調(diào)用參數(shù)示例

!/bin/bash

函數(shù)的使用場(chǎng)景二

dayin(){
echo "wo de mingzi shi $1"
}
dayin 111

函數(shù)調(diào)用腳本傳參

!/bin/bash

函數(shù)傳參演示

定義傳參數(shù)函數(shù)

dayin(){
echo "wode mignzi shi $1"
}

函數(shù)傳參

dayin $1
腳本傳多參,函數(shù)分別調(diào)用示例

!/bin/bash

函數(shù)的使用場(chǎng)景二

dayin(){
echo "wo de mingzi shi 1" echo "wo de mingzi shi2"
echo "wo de mingzi shi $3"
}
dayin 111 df dfs


4.3 第一階段綜合案例
需求
1、zonghe.sh 腳本執(zhí)行時(shí)候需要添加參數(shù)才能執(zhí)行
參數(shù)和功能詳情如下:
參數(shù) 執(zhí)行效果
start 服務(wù)啟動(dòng)中...
stop 服務(wù)關(guān)閉中...
restart 服務(wù)重啟中...
* 腳本幫助信息...
2、參數(shù)的數(shù)量有限制,只能是1個(gè),多余一個(gè)會(huì)提示腳本的幫助信息
3、幫助信息使用函數(shù)來(lái)實(shí)現(xiàn)
信息內(nèi)容:腳本 zonghe.sh 使用方式 zonghe.sh [ start|stop|restart ]
知識(shí)點(diǎn)分析:
1、zonghe.sh 腳本執(zhí)行時(shí)候需要添加參數(shù)才能執(zhí)行
腳本傳參、case語(yǔ)句
2、參數(shù)的數(shù)量有限制,只能是1個(gè),多余一個(gè)會(huì)提示腳本的幫助信息
參數(shù)數(shù)量、條件表達(dá)式(驗(yàn)證+數(shù)字)、if語(yǔ)句
3、幫助信息使用函數(shù)來(lái)實(shí)現(xiàn)
函數(shù)定義+調(diào)用
4、if語(yǔ)句和case語(yǔ)句嵌套
if語(yǔ)句在外,case語(yǔ)句在內(nèi)
腳本編寫(xiě)流程:
1、先寫(xiě)主流程框架
2、完善函數(shù)功能
3、完善需求功能
代碼實(shí)踐

!/bin/bash

定義本地變量

arg="$1"

腳本幫助信息

usage(){
echo "腳本 0 的使用方式是:0 [ start|stop|restart ]"
}

函數(shù)主框架

if [ # -eq 1 ] then case "{arg}" in
start)
echo "服務(wù)啟動(dòng)中..."
;;
stop)
echo "服務(wù)關(guān)閉中..."
;;
restart)
echo "服務(wù)重啟中..."
;;
*)
usage
;;
esac
else
usage
fi
第 5 章 代碼發(fā)布
5.1 代碼發(fā)布簡(jiǎn)介
到現(xiàn)在為止我們學(xué)會(huì)了多個(gè)開(kāi)發(fā)項(xiàng)目案例,也知道工作中如何做一個(gè)項(xiàng)目,但是一個(gè)項(xiàng)目方案的如何部署到公司的線(xiàn)上服務(wù)器上,部署過(guò)程中都會(huì)經(jīng)歷哪些事情呢?接下來(lái)我們好好的來(lái)梳理一下。
5.1.1 代碼發(fā)布介紹
什么是代碼發(fā)布?
代碼發(fā)布就是一句話(huà):將我們的代碼放到一臺(tái)公司的互聯(lián)網(wǎng)服務(wù)器上。
那么我們應(yīng)該怎么來(lái)理解這句話(huà)呢?我們從三個(gè)方面來(lái)理解他。

如何理解這句話(huà)?
發(fā)布什么?
代碼 經(jīng)過(guò)測(cè)試,功能完善,沒(méi)有問(wèn)題的代碼
發(fā)布到哪里?
服務(wù)器 所有人都能訪(fǎng)問(wèn)的到的一臺(tái)服務(wù)器(有公網(wǎng)IP)
idc機(jī)房、阿里云、亞馬遜、騰訊云、華為云、....
發(fā)布的效果?
web網(wǎng)頁(yè)對(duì)外展示

5.1.2 發(fā)布方式
常見(jiàn)的代碼發(fā)布方式有兩種:手工方式和腳本方式。
這兩種方式有什么區(qū)別呢?我們接下來(lái)好好的對(duì)比分析一下。

手工發(fā)布代碼 步行

干擾因素多
不安全

腳本發(fā)布代碼 坐車(chē)

干擾因素少
安全
5.2 代碼發(fā)布流程
5.2.1 流程簡(jiǎn)介
接下來(lái)我們來(lái)好好的說(shuō)一下部署的流程:


注: 大型腳本流程
5.2.2 流程詳解
接下來(lái)我們來(lái)對(duì)每個(gè)過(guò)程進(jìn)行一個(gè)仔細(xì)的敘述
部署場(chǎng)景:
兩臺(tái)主機(jī)做部署動(dòng)作

注意:
部署的文件就是兩臺(tái)主機(jī)右上角的紅色內(nèi)容

獲取代碼

代碼倉(cāng)庫(kù)
    集中式的:   svn
    分布式的:   git

區(qū)別:
svn的幾乎所有操作命令,都集中在我和代碼倉(cāng)庫(kù)服務(wù)器處于網(wǎng)絡(luò)連接狀態(tài)。
git的幾乎所有操作命令,可以在本地完成,和代碼倉(cāng)庫(kù)服務(wù)器是否連接無(wú)關(guān)。

公司的代碼倉(cāng)庫(kù):
    私有倉(cāng)庫(kù)    gitlab
        內(nèi)部服務(wù)器或者公網(wǎng)服務(wù)器
        
倉(cāng)庫(kù)權(quán)限
    只有項(xiàng)目的開(kāi)發(fā)人員才有權(quán)限,項(xiàng)目之外的人沒(méi)有權(quán)限
    
代碼權(quán)限:
    開(kāi)發(fā)、管理、查看
    
提交的方式:
    代碼版本號(hào)

打包代碼
場(chǎng)景演示:

目的:
    減少傳輸文件數(shù)量
    減小傳輸文件大小
    增強(qiáng)傳輸速率
    
常見(jiàn)打包方式:
    windows:
        zip、rar...
    linux:
        tar、zip...

傳輸代碼
場(chǎng)景效果:

傳輸方式:
    有網(wǎng)情況下

多種方式:
git、ftp、scp、共享掛載 cp、rsync
沒(méi)有網(wǎng)情況下
物理方式:
U盤(pán)或者硬盤(pán)
關(guān)閉應(yīng)用
代碼所在的服務(wù)用到了什么應(yīng)用,就關(guān)閉什么應(yīng)用
關(guān)閉的順序:
先關(guān)閉離客戶(hù)近的,后關(guān)閉離客戶(hù)遠(yuǎn)的

解壓代碼:
tar xf ...

放置代碼
為了避免我們?cè)诜胖么a過(guò)程中,對(duì)老文件造成影響,所以我們放置代碼一般分為兩步:備份老文件和放置新文件。
備份原文件

    放置新文件

注意:
    兩個(gè)文件的名稱(chēng)是一樣的,只是內(nèi)容不同
    對(duì)整個(gè)應(yīng)用項(xiàng)目來(lái)說(shuō),兩個(gè)文件沒(méi)有區(qū)別

開(kāi)啟應(yīng)用
剛才關(guān)閉了什么應(yīng)用就開(kāi)啟什么應(yīng)用
開(kāi)啟的順序:
先開(kāi)啟離客戶(hù)遠(yuǎn)的,后開(kāi)啟離客戶(hù)近的

檢查
查看瀏覽器效果或者netstat -tnulp查看系統(tǒng)開(kāi)放的端口


5.2.3 技術(shù)關(guān)鍵點(diǎn)
文件的壓縮和解壓
文件的壓縮
壓縮格式:
tar zcvf 壓縮后的文件名 將要壓縮的文件
文件的解壓
解壓格式:
tar xf 壓縮后的文件名

命令參數(shù)詳解
z 指定壓縮文件的格式為 tar.gz
c 表示壓縮
v 顯示詳細(xì)過(guò)程
f 指定壓縮文件
x 解壓

查看壓縮文件內(nèi)容
zcat 壓縮文件

文件的傳輸
scp傳輸工具:
命令格式:
scp 要傳輸?shù)奈募? 要放置的位置

    將本地文件推送到遠(yuǎn)程主機(jī)
        scp python.tar.gz root@192.168.8.15:/root/
    將遠(yuǎn)程主機(jī)的文件拉取到本地
        scp root@192.168.8.15:/root/python.tar.gz ./

遠(yuǎn)端主機(jī)文件放置位置的表示形式:
遠(yuǎn)程連接的用戶(hù)@遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)的目錄路徑
遠(yuǎn)端主機(jī)文件位置的表示形式:
遠(yuǎn)程連接的用戶(hù)@遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)的文件路徑

文件的備份
文件的備份要有一定的標(biāo)志符號(hào),我們就使用目前通用的時(shí)間戳的形式來(lái)表示

date命令詳解:
命令格式:date [option]
常見(jiàn)參數(shù):
%F 顯示當(dāng)前日期格式,%Y-%m-%d
%T 顯示當(dāng)前時(shí)間格式,%H:%M:%S

演示效果:
顯示當(dāng)前日期

date +%F

2017-09-28
顯示當(dāng)前時(shí)間

date +%T

03:06:30

根據(jù)上面的參數(shù)介紹,我們可以指定命令顯示的格式,
年月日:date +%Y%m%d
時(shí)分秒:date +%H%M%S

演示效果:
顯示當(dāng)前日期

date +%Y%m%d

20170928
顯示當(dāng)前時(shí)間

date +%H%M%S

030643

指定時(shí)間戳格式:
年月日時(shí)分秒:date +%Y%m%d%H%M%S

時(shí)間戳演示效果:
指定的時(shí)間戳格式

date +%Y%m%d%H%M%S

20170928030742

備份命令效果格式:
方式一:復(fù)制備份
cp nihao nihao-(date +%Y%m%d%H%M%S) 方式二:移動(dòng)備份 mv nihao nihao-(date +%Y%m%d%H%M%S)
我們?yōu)榱吮苊庠诜胖眯挛募r(shí)候,出現(xiàn)驗(yàn)證操作,我們確定采用方式二:


練習(xí)案例:
1、在主機(jī)1上創(chuàng)建一個(gè)目錄/data/tar-ceshi/,在目錄里面創(chuàng)建兩個(gè)文件,內(nèi)容分別如下:
文件名 內(nèi)容
file1.txt file1
file2.txt file2
2、對(duì)目錄tar-ceshi進(jìn)行壓縮
3、對(duì)目錄tar-ceshi進(jìn)行時(shí)間戳備份
4、將壓縮包文件傳輸?shù)竭h(yuǎn)端主機(jī)2
5、在主機(jī)2上解壓 壓縮包文件
6、在主機(jī)2上修改壓縮包文件內(nèi)容。然后再次壓縮
7、在主機(jī)1上拉取主機(jī)2的壓縮包文件
8、使用命令查看壓縮包文件的內(nèi)容
命令執(zhí)行效果:
主機(jī)1操作命令
1、
mkdir /data/tar-ceshi -p
cd /data
echo 'file1' > tar-ceshi/file1.txt
echo 'file1' > tar-ceshi/file1.txt
2、tar zcvf tar-ceshi.tar.gz tar-ceshi
3、mv tar-ceshi tar-ceshi-$(date +%Y%m%d%H%M%S)
4、scp tar-ceshi.tar.gz root@192.168.8.15:/tmp
主機(jī)2操作命令
5、
cd /tmp
tar xf tar-ceshi.tar.gz
6、
echo 'file3' >> tar-ceshi/file1.txt
tar zcvf tar-ceshi-1.tar.gz tar-ceshi
主機(jī)1操作命令
7、scp root@192.168.8.15:/tmp/tar-ceshi-1.tar.gz ./
8、zcat tar-ceshi-1.tar.gz
第 6 章 環(huán)境部署
環(huán)境部署這塊,我們需要有一個(gè)項(xiàng)目的基礎(chǔ)環(huán)境,然后在這個(gè)基礎(chǔ)環(huán)境上,再根據(jù)項(xiàng)目需求搭建一個(gè)能讓項(xiàng)目代碼正常運(yùn)行的環(huán)境。所以這塊的知識(shí),我們從三個(gè)方面來(lái)學(xué)習(xí)
基礎(chǔ)環(huán)境
方案分析
項(xiàng)目環(huán)境部署
6.1 基礎(chǔ)環(huán)境
6.1.1 基礎(chǔ)目錄環(huán)境
創(chuàng)建基本目錄

mkdir /data/{server,logs,backup,softs,virtual,scripts,codes} -p

ls /data/

backup logs scripts server softs virtual codes
查看
admin-1@ubuntu:/data# tree -L 1 /data/
/data/
├── backup 備份
├── codes 代碼
├── logs 日志
├── scripts 腳本
├── server 服務(wù)
├── softs 軟件
└── virtual 虛擬環(huán)境
6.1.2 主機(jī)網(wǎng)絡(luò)環(huán)境
問(wèn)題:
我們上面進(jìn)行文件傳輸?shù)臅r(shí)候,發(fā)現(xiàn)一個(gè)問(wèn)題,每次進(jìn)行文件傳輸都需要進(jìn)行密碼驗(yàn)證,這對(duì)我們來(lái)說(shuō),有些一丁點(diǎn)不舒服,那么有沒(méi)有辦法,讓我痛苦一點(diǎn)?
答案就是:主機(jī)間免密碼認(rèn)證

知識(shí)點(diǎn):
什么是主機(jī)間免密碼認(rèn)證?
就是我和另外一臺(tái)主機(jī)做任何事情,不需要輸入密碼認(rèn)證,非常很方便。

方案詳解
我們要做主機(jī)間免密碼認(rèn)證需要做三個(gè)動(dòng)作
1、本機(jī)生成密鑰對(duì)
2、對(duì)端機(jī)器使用公鑰文件認(rèn)證
3、驗(yàn)證

方案實(shí)施
1、生成秘鑰對(duì)
ssh-keygen -t rsa
-t 指定秘鑰的類(lèi)型
rsa 秘鑰類(lèi)型

        秘鑰目錄:/root/.ssh/
            私鑰      id_rsa                  鑰匙
            公鑰      id_rsa.pub          鎖
            
    2、編輯認(rèn)證文件
        admin-1@ubuntu:~/.ssh# cat /root/.ssh/authorized_keys 
        ssh-rsa AAAAB3N...PVp admin-1@ubuntu
        注意:
            認(rèn)證文件內(nèi)容和8.15機(jī)器的公鑰文件內(nèi)容一致
            保證文件內(nèi)容是一整行
            
    3、編輯ssh配置文件
        admin-1@ubuntu:~/.ssh# cat /etc/ssh/sshd_config
        ...
            AuthorizedKeysFile  %h/.ssh/authorized_keys
        注意: 
            直接取消該行的注釋即可
            
    4、配置文件生效
        重啟ssh服務(wù)
        /etc/init.d/ssh restart
        
    5、驗(yàn)證操作
        ssh root@192.168.8.15
        
    1和5是在8.14上操作
    2-4是在8.15上操作

6.2 方案分析
6.2.1 需求
需求:
部署一個(gè)環(huán)境,支持我們的django項(xiàng)目正常運(yùn)行
6.2.2 需求分析
分析:
2、python環(huán)境 ---> 3、python虛擬環(huán)境
1、django環(huán)境部署
4、django軟件安裝
5、項(xiàng)目基本操作
6、應(yīng)用基本操作
7、view和url配置
8、問(wèn)題:只有本機(jī)能訪(fǎng)問(wèn)
9、方案代理---- 10、nginx
11、nginx實(shí)現(xiàn)代理
13、pcre軟件安裝
12、nginx軟件安裝
14、nginx基本操作
15、nginx代理的配置
16、目錄結(jié)構(gòu)
17、查看配置文件
18、找到對(duì)應(yīng)的代理配置項(xiàng)
19、啟動(dòng)django
20、啟動(dòng)nginx
21、整個(gè)項(xiàng)目調(diào)試
6.2.3 部署方案
環(huán)境部署方案
一、django環(huán)境部署
1.1 python虛擬環(huán)境
1.2 django環(huán)境部署
1.2.1 django軟件安裝
1.2.2 項(xiàng)目基本操作
1.2.3 應(yīng)用基本操作
1.2.4 view和url配置
二、nginx代理django
2.1 nginx軟件安裝
2.1.1 pcre軟件安裝
2.1.2 nginx軟件安裝
2.1.3 nginx基本操作
2.2 nginx代理配置
2.2.1 目錄結(jié)構(gòu)查看
2.2.2 配置文件查看
2.2.3 編輯代理配置項(xiàng)
三、項(xiàng)目調(diào)試
3.1 啟動(dòng)軟件
3.1.1 啟動(dòng)django
3.1.2 啟動(dòng)nginx
3.2 整個(gè)項(xiàng)目調(diào)試

6.3 項(xiàng)目環(huán)境部署
6.3.1 python虛擬環(huán)境
軟件安裝
安裝虛擬環(huán)境軟件
apt-get install python-virtualenv -y
虛擬環(huán)境基本操作
創(chuàng)建
virtualenv -p /usr/bin/python3.5 venv
進(jìn)入
source venv/bin/activate
退出
deactivate
刪除
rm -rf venv
6.3.2 django環(huán)境
django軟件安裝
注意:先進(jìn)入虛擬環(huán)境
解壓
cd /data/soft
tar xf Django-1.10.7.tar.gz
查看
cd Django-1.10.7
cat INSTALL or README
安裝
python setup.py install

拓展知識(shí)點(diǎn):
python類(lèi)型軟件的安裝流程
普通:
解壓 安裝
特殊:
解壓 編譯 安裝

        編譯:python setup.py build

django項(xiàng)目操作
創(chuàng)建項(xiàng)目
cd /data/server
django-admin startproject itcast
django應(yīng)用操作
創(chuàng)建應(yīng)用
cd /data/server/itcast
python manage.py startapp test1
注冊(cè)應(yīng)用

vim itcast/settings.py

INSTALL_APP = [
。。。
'test1',
]
view和url配置
需求:
訪(fǎng)問(wèn)django的頁(yè)面請(qǐng)求為:127.0.0.1:8000/hello/,頁(yè)面返回效果為:itcast v1.0
分析:
views文件定制邏輯流程函數(shù)
urls文件定制路由跳轉(zhuǎn)功能

view 配置文件生效

admin-1@ubuntu:/data/soft# cat /data/server/itcast/test1/views.py
from django.shortcuts import render
from django.http import HttpResponse

Create your views here.

def hello(resquest):
return HttpResponse("itcast V1.0")

url文件配置

admin-1@ubuntu:/data/soft# cat /data/server/itcast/itcast/urls.py
...
from test1.views import *

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^hello/$', hello),
]

啟動(dòng)django:

cd /data/server/itcast
python manage.py runserver


6.3.3 nginx環(huán)境
pcre軟件安裝
解壓
cd /data/soft/
tar xf pcre-8.39.tar.gz
查看幫助
cd pcre-8.39
INSTALL 或者 README
配置
./configure
編譯
make
安裝
make install

拓展知識(shí)點(diǎn):
linux中軟件安裝的一般流程
解壓
tar
解壓文件,獲取真正的配置文件
配置
configure
根據(jù)默認(rèn)的配置項(xiàng)或者更改配置項(xiàng),生成編譯配置文件(Makefile)
編譯
make
根據(jù) Makefile 內(nèi)容,編譯生成指定的軟件所需要的所有文件
安裝
make install
將編譯生成的所有文件,轉(zhuǎn)移到軟件指定安裝的目錄下面
--prefix
nginx軟件安裝
解壓
cd /data/soft/
tar xf nginx-1.10.2.tar.gz
配置
cd nginx-1.10.2/
./configure --prefix=/data/server/nginx --without-http_gzip_module
編譯
make
安裝
make install

nginx簡(jiǎn)單操作
檢查
/data/server/nginx/sbin/nginx -t
開(kāi)啟
/data/server/nginx/sbin/nginx
關(guān)閉
/data/server/nginx/sbin/nginx -s stop
重載
/data/server/nginx/sbin/nginx -s reload

常見(jiàn)問(wèn)題
突發(fā)問(wèn)題:
admin-1@ubuntu:/data/server/nginx# ./sbin/nginx -t
./sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

    分析:
        1、先看報(bào)錯(cuò)
        2、思考,是否報(bào)錯(cuò)真實(shí)有效
            分析: 誰(shuí)錯(cuò)了
            
        3、查找文件
            全名找不到,我們使用正則
        4、找到文件,我沒(méi)有問(wèn)題
            nginx默認(rèn)找?guī)煳募穆窂接袉?wèn)題
        5、解決

解決:
admin-1@ubuntu:/data/soft/nginx-1.10.2# ldd /data/server/nginx/sbin/nginx
linux-vdso.so.1 => (0x00007ffdb9154000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa59379b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa59357e000)
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fa593345000)
libpcre.so.1 => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa592f7c000)
/lib64/ld-linux-x86-64.so.2 (0x0000564bfef41000)
查找文件:
admin-1@ubuntu:/data/soft/nginx-1.10.2# find / -name "libpcre.so.1"
/data/soft/pcre-8.39/.libs/libpcre.so.1
/usr/local/lib/libpcre.so.1
...
鏈接該文件
admin-1@ubuntu:/data/soft/nginx-1.10.2# ln -s /usr/local/lib/libpcre.so.1 /lib/x86_64-linux-gnu/
再次檢查一下nginx的配置文件
admin-1@ubuntu:/data/soft/nginx-1.10.2# /data/server/nginx/sbin/nginx -t
nginx: the configuration file /data/server/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /data/server/nginx/conf/nginx.conf test is successful


6.3.4 nginx代理django
nginx配置簡(jiǎn)介
nginx的目錄結(jié)構(gòu)
admin-1@ubuntu:/data/server/nginx# tree -L 2 /data/server/nginx/
/data/server/nginx/
├── ...
├── conf 配置文件目錄
│ ...
│ ├── nginx.conf 默認(rèn)的配置文件
│ ...
├── ...
├── html 網(wǎng)頁(yè)文件
│ ├── 50x.html
│ └── index.html
├── logs 日志目錄
│ ├── access.log
│ └── error.log
├── ...
├── sbin 執(zhí)行文件目錄
│ └── nginx
├── ...

nginx配置文件介紹
全局配置段
http配置段
server配置段 項(xiàng)目或者應(yīng)用
location配置段 url配置

nginx代理配置
案例需求:
訪(fǎng)問(wèn)地址 192.168.8.14/hello/ 跳轉(zhuǎn)到 127.0.0.1:8000/hello/的django服務(wù)來(lái)處理hello請(qǐng)求

代理是什么?
哥,這事交給我就行了,您就甭操心了。
編輯配置文件實(shí)現(xiàn)代理功能
配置內(nèi)容
62: location /hello/ {
63: proxy_pass http://127.0.0.1:8000;
64: }
注釋?zhuān)?br> 當(dāng)我訪(fǎng)問(wèn)地址是
配置文件生效
/data/server/nginx/sbin/nginx -t
/data/server/nginx/sbin/nginx -s reload


第 7 章 手工代碼發(fā)布
7.1 方案分析
發(fā)布需求:
手工方式部署代碼

發(fā)布方案:
    獲取代碼

sed -i 's#文件原始的內(nèi)容#替換后的內(nèi)容#g' 要更改到文件名

    打包代碼


    傳輸代碼

    關(guān)閉應(yīng)用
    解壓代碼
    放置代碼
        備份老文件

        放置新文件

    開(kāi)啟應(yīng)用
    檢查

注意:
獲取代碼和打包代碼在代碼倉(cāng)庫(kù)主機(jī)上進(jìn)行操作
其他操作,都在線(xiàn)上服務(wù)器進(jìn)行操作

7.2 方案實(shí)施
獲取代碼
mkdir /data/codes -p
cd /data/codes
sed -i 's#1.0#1.1#' django/views.py
sed -i 's#原內(nèi)容#替換后內(nèi)容#g' 文件

打包代碼
cd /data/codes/
tar zcf django.tar.gz django

注意:
前面兩步在代碼倉(cāng)庫(kù)主機(jī)上操作

傳輸代碼
cd /data/codes/
scp root@192.168.8.15:/data/codes/django.tar.gz ./
關(guān)閉應(yīng)用
關(guān)閉nginx應(yīng)用
/data/server/nginx/sbin/nginx -s stop

關(guān)閉django應(yīng)用
    根據(jù)端口查看進(jìn)程號(hào),
        lsof -Pti :8000
    殺死進(jìn)程號(hào)
        kill 56502

一條命令搞定它:
kill $(lsof -Pti :8000)

解壓代碼
cd /data/codes
tar xf django.tar.gz

放置代碼
備份老文件
需求:備份的格式:
文件名-時(shí)間戳
時(shí)間戳:年月日時(shí)分秒
date +%Y%m%d%H%M%S
mv /data/server/itcast/test1/views.py /data/backup/views.py-$(date +%Y%m%d%H%M%S)
放置新文件
cd /data/codes
mv django/views.py /data/server/itcast/test1/

開(kāi)啟應(yīng)用
開(kāi)啟django應(yīng)用
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
開(kāi)啟nginx應(yīng)用
/data/server/nginx/sbin/nginx

檢查
netstat -tnulp | grep ':80'


注: 大型腳本之命令填充
第 8 章 腳本發(fā)布代碼
關(guān)于腳本發(fā)布代碼部分呢,我們將這個(gè)代碼部署流程拆分成兩部分:簡(jiǎn)單腳本(遠(yuǎn)端主機(jī)上執(zhí)行)和大型腳本(線(xiàn)上機(jī)器執(zhí)行),這樣我們能從兩個(gè)方面來(lái)學(xué)習(xí)生產(chǎn)中的腳本如何編寫(xiě)。首先來(lái)說(shuō)簡(jiǎn)單腳本的編寫(xiě)
8.1 簡(jiǎn)單腳本編寫(xiě)
簡(jiǎn)單腳本我們從四個(gè)方面來(lái)學(xué)習(xí):
1、命令羅列實(shí)現(xiàn)功能
2、固定內(nèi)容變量實(shí)現(xiàn)
3、功能函數(shù)實(shí)現(xiàn)
4、遠(yuǎn)程執(zhí)行命令
8.1.1 命令羅列
目的:
實(shí)現(xiàn)代碼倉(cāng)庫(kù)主機(jī)上的操作命令功能即可

實(shí)現(xiàn)簡(jiǎn)單的功能--- 簡(jiǎn)單的命令羅列

!/bin/bash

功能:打包代碼

腳本名:tar_code.sh

作者:itcast

版本:V 0.1

聯(lián)系方式:www.itcast.cn

cd /data/codes
[ -f django.tar.gz ] && rm -f django.tar.gz
tar zcf django.tar.gz django
腳本編寫(xiě)完成后,進(jìn)行測(cè)試:
sed -i 's#1.1#1.2#' /data/codes/django/views.py
bash /data/scripts/tar_code.sh
查看壓縮文件內(nèi)容
zcat django.tar.gz
8.1.2 固定內(nèi)容變量化
問(wèn)題:
腳本里面的手寫(xiě)的固定的內(nèi)容太多了,更改時(shí)候費(fèi)勁

腳本優(yōu)化之 固定內(nèi)容變量化

!/bin/bash

功能:打包代碼

腳本名:tar_code.sh

作者:itcast

版本:V 0.2

聯(lián)系方式:www.itcast.cn

FILE='django.tar.gz'
CODE_DIR='/data/codes'
CODE_PRO='django'

cd "{CODE_DIR}" [ -f "{FILE}" ] && rm -f "{FILE}" tar zcf "{FILE}" "${CODE_PRO}"
腳本編寫(xiě)完成后,進(jìn)行測(cè)試:
sed -i 's#1.2#1.3#' /data/codes/django/views.py
bash /data/scripts/tar_code.sh
查看壓縮文件內(nèi)容
zcat django.tar.gz
8.1.3 功能函數(shù)化
需求:
三條命令其實(shí)是一個(gè)組合,實(shí)現(xiàn)的是一個(gè)功能
腳本優(yōu)化之 功能函數(shù)化

!/bin/bash

功能:打包代碼

腳本名:tar_code.sh

作者:itcast

版本:V 0.3

聯(lián)系方式:www.itcast.cn

FILE='django.tar.gz'
CODE_DIR='/data/codes'
CODE_PRO='django'

code_tar(){
cd "{CODE_DIR}" [ -f "{FILE}" ] && rm -f "{FILE}" tar zcf "{FILE}" "${CODE_PRO}"
}
code_tar
腳本編寫(xiě)完成后,進(jìn)行測(cè)試:
sed -i 's#1.2#1.3#' /data/codes/django/views.py
bash /data/scripts/tar_code.sh
查看壓縮文件內(nèi)容
zcat /data/codes/django.tar.gz
8.1.4 遠(yuǎn)程執(zhí)行
遠(yuǎn)程命令執(zhí)行
格式:
ssh 遠(yuǎn)程主機(jī)登錄用戶(hù)名@遠(yuǎn)程主機(jī)ip地址 "執(zhí)行命令"
效果
admin-1@ubuntu:/data/server/itcast# ssh root@192.168.8.15 "ifconfig eth0"
eth0 Link encap:Ethernet HWaddr 00:0c:29:f7:ca:d4
inet addr:192.168.8.15 Bcast:192.168.56.255 Mask:255.255.255.0
...

遠(yuǎn)程執(zhí)行腳本測(cè)試
遠(yuǎn)程更新文件內(nèi)容
ssh root@192.168.8.15 "sed -i /'s#1.4#1.5#' /data/codes/django/views.py"
遠(yuǎn)程查看腳本
ssh root@192.168.8.15 "ls /data/scripts"
遠(yuǎn)程執(zhí)行腳本
ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh"
遠(yuǎn)程檢查更新效果
ssh root@192.168.8.15 "zcat /data/codes/django.tar.gz"
8.2 大型腳本編寫(xiě)
本地是指線(xiàn)上服務(wù)器主機(jī)(192.168.8.14)
我們先來(lái)回顧一下代碼發(fā)布流程圖
編寫(xiě)大型腳本有一個(gè)流程:
一、腳本框架
二、命令填充
三、完善功能
增加日志功能
增加鎖文件功能
增加主函數(shù)邏輯
增加參數(shù)安全措施

8.2.1 腳本框架
為什么?
1、命令多
2、功能多
3、不好組合

需求:
先將腳本所涉及的所有業(yè)務(wù)流程跑通

方案:
使用函數(shù)來(lái)體現(xiàn)

腳本實(shí)施:

!/bin/bash

功能:打包代碼

腳本名:deploy.sh

作者:itcast

版本:V 0.1

聯(lián)系方式:www.itcast.cn

獲取代碼

get_code(){
echo "獲取代碼"
}

打包代碼

tar_code(){
echo "打包代碼"
}

傳輸代碼

scp_code(){
echo "傳輸代碼"
}

關(guān)閉應(yīng)用

stop_serv(){
echo "關(guān)閉應(yīng)用"
echo "關(guān)閉nginx應(yīng)用"
echo "關(guān)閉django應(yīng)用"
}

解壓代碼

untar_code(){
echo "解壓代碼"
}

放置代碼

fangzhi_code(){
echo "放置代碼"
echo "備份老文件"
echo "放置新文件"
}

開(kāi)啟應(yīng)用

start_serv(){
echo "開(kāi)啟應(yīng)用"
echo "開(kāi)啟django應(yīng)用"
echo "開(kāi)啟nginx應(yīng)用"
}

檢查

check(){
echo "檢查項(xiàng)目"
}

部署函數(shù)

deploy_pro(){
get_code
tar_code
scp_code
stop_serv
untar_code
fangzhi_code
start_serv
check
}

主函數(shù)

main(){
deploy_pro
}

執(zhí)行主函數(shù)

main
8.2.2 命令填充
需求:
在流程跑通的情況下,執(zhí)行完整的代碼部署過(guò)程
方案:
在腳本框架中,填寫(xiě)執(zhí)行成功的命令

腳本實(shí)施:

!/bin/bash

功能:打包代碼

腳本名:deploy.sh

作者:itcast

版本:V 0.2

聯(lián)系方式:www.itcast.cn

獲取代碼

get_code(){
echo "獲取代碼"
}

打包代碼

tar_code(){
echo "打包代碼"
ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh"
}

傳輸代碼

scp_code(){
echo "傳輸代碼"
cd /data/codes
[ -f django.tar.gz ] && rm -f django.tar.gz
scp root@192.168.8.15:/data/codes/django.tar.gz ./
}

關(guān)閉應(yīng)用

stop_serv(){
echo "關(guān)閉應(yīng)用"
echo "關(guān)閉nginx應(yīng)用"
/data/server/nginx/sbin/nginx -s stop
echo "關(guān)閉django應(yīng)用"
kill $(lsof -Pti :8000)
}

解壓代碼

untar_code(){
echo "解壓代碼"
cd /data/codes
tar xf django.tar.gz
}

放置代碼

fangzhi_code(){
echo "放置代碼"
echo "備份老文件"
mv /data/server/itcast/test1/views.py /data/backup/views.py-$(date +%Y%m%d%H%M%S)
echo "放置新文件"
mv /data/codes/django/views.py /data/server/itcast/test1/
}

開(kāi)啟應(yīng)用

start_serv(){
echo "開(kāi)啟應(yīng)用"
echo "開(kāi)啟django應(yīng)用"
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
echo "開(kāi)啟nginx應(yīng)用"
/data/server/nginx/sbin/nginx
}

檢查

check(){
echo "檢查項(xiàng)目"
netstat -tnulp | grep ':80'
}

...
8.2.3 增加日志功能
需求:
1、追蹤記錄
2、數(shù)據(jù)說(shuō)話(huà)

方案:
增加日志功能
1、日志文件
/data/logs/deploy.log
2、日志格式
日期 時(shí)間 腳本名稱(chēng) 步驟

知識(shí)點(diǎn):
文件內(nèi)容追加: >>
日期:date +%F
時(shí)間:date +%T
腳本:$0

腳本實(shí)施:

!/bin/bash

...
LOG_FILE='/data/logs/deploy.log'

增加日志功能

write_log(){
DATE=(date +%F) TIME=(date +%T)
buzhou="1" echo "{DATE} {TIME}0 : {buzhou}" >> "{LOG_FILE}"
}

獲取代碼

get_code(){
...
write_log "獲取代碼"
}

打包代碼

tar_code(){
...
write_log "打包代碼"
}

傳輸代碼

scp_code(){
...
write_log "傳輸代碼"
}

關(guān)閉應(yīng)用

stop_serv(){
...
write_log "關(guān)閉應(yīng)用"
...
write_log "關(guān)閉nginx應(yīng)用"
...
write_log "關(guān)閉django應(yīng)用"
}

解壓代碼

untar_code(){
...
write_log "解壓代碼"
}

放置代碼

fangzhi_code(){
...
write_log "放置代碼"
...
write_log "備份老文件"
...
write_log "放置新文件"
}

開(kāi)啟應(yīng)用

start_serv(){
...
write_log "開(kāi)啟應(yīng)用"
...
write_log "開(kāi)啟django應(yīng)用"
...
write_log "開(kāi)啟nginx應(yīng)用"
}

檢查

check(){
...
write_log "檢查項(xiàng)目"
}

...

8.2.4 增加鎖文件功能
需求:
同一時(shí)間段內(nèi),只允許有一個(gè)用戶(hù)來(lái)執(zhí)行這個(gè)腳本
如果腳本執(zhí)行的時(shí)候,有人在執(zhí)行,那么輸出報(bào)錯(cuò):
腳本 deploy.sh 正在運(yùn)行,請(qǐng)稍候...

設(shè)計(jì):
    1、鎖文件       /tmp/deploy.pid

2、存在鎖文件時(shí)候,輸出報(bào)錯(cuò)信息
3、腳本執(zhí)行的時(shí)候,需要?jiǎng)?chuàng)建鎖文件
4、腳本執(zhí)行結(jié)束的時(shí)候,需要?jiǎng)h除鎖文件

知識(shí)點(diǎn):
條件和結(jié)果: 雙分支if語(yǔ)句
文件表達(dá)式: -f file_name
驗(yàn)證表達(dá)式: [ 表達(dá)式 ]
創(chuàng)建和刪除命令:touch、rm -f

腳本實(shí)施

!/bin/bash

...
PID_FILE='/tmp/deploy.pid'
...

增加鎖文件功能

add_lock(){
echo "增加鎖文件"
touch "${PID_FILE}"
write_log "增加鎖文件"
}

刪除鎖文件功能

del_lock(){
echo "刪除鎖文件"
rm -f "${PID_FILE}"
write_log "刪除鎖文件"
}

部署函數(shù)

deploy_pro(){
add_lock
...
del_lock
}

腳本報(bào)錯(cuò)信息

err_msg(){
echo "腳本 $0 正在運(yùn)行,請(qǐng)稍候..."
}

主函數(shù)

main(){
if [ -f "${PID_FILE}" ]
then
err_msg
else
deploy_pro
fi
}

執(zhí)行主函數(shù)

main

8.2.5 腳本流程知識(shí)點(diǎn)填充
需求:
如果我給腳本輸入的參數(shù)是deploy,那么腳本才執(zhí)行,否則的話(huà),提示該腳本的使用幫助信息,然后退出
提示信息:腳本 deploy.sh 的使用方式: deploy.sh [ deploy ]
分析:
1、腳本傳參,就需要在腳本內(nèi)部進(jìn)行調(diào)用參數(shù)
2、腳本的幫助信息
3、腳本內(nèi)容就需要對(duì)傳參的內(nèi)容進(jìn)行判斷

知識(shí)點(diǎn):
1、shell內(nèi)置變量:$n
2、幫助信息: 簡(jiǎn)單函數(shù)定義和調(diào)用
3、內(nèi)容判斷: 多if語(yǔ)句或者case語(yǔ)句

方案:
1、腳本的傳參
腳本執(zhí)行:bash deploy.sh deploy
位置參數(shù)的調(diào)用: 1 2、腳本的幫助信息 定義一個(gè)usage函數(shù),然后調(diào)用。 提示信息格式: 腳本 deploy.sh 的使用方式: deploy.sh [ deploy ] 3、內(nèi)容判斷 main函數(shù)體調(diào)用函數(shù)傳參:1
在main函數(shù)中,結(jié)合case語(yǔ)句,對(duì)傳入的參數(shù)進(jìn)行匹配
如果傳入?yún)?shù)內(nèi)容是"deploy",那么就執(zhí)行代碼部署流程
如果傳入?yún)?shù)內(nèi)容不是"deploy",那么輸出腳本的幫助信息
if語(yǔ)句和case語(yǔ)句的結(jié)合
if語(yǔ)句在外,case語(yǔ)句在內(nèi)
case語(yǔ)句在外,if語(yǔ)句在內(nèi)

腳本實(shí)施

!/bin/bash

...

腳本幫助信息

usage(){
echo "腳本 0 的使用方式:0 [deploy]"
exit
}

主函數(shù)

main(){
case "1" in "deploy") if [ -f "{PID_FILE}" ]
then
err_msg
else
deploy_pro
fi
;;
*)
usage
;;
esac
}

執(zhí)行主函數(shù)

main $1
8.2.6 輸入?yún)?shù)安全優(yōu)化
需求:
對(duì)腳本傳入的參數(shù)的數(shù)量進(jìn)行判斷,如果參數(shù)數(shù)量不對(duì),提示腳本的使用方式,然后退出

分析:
1、腳本參數(shù)數(shù)量判斷
2、條件判斷
數(shù)量對(duì),那么執(zhí)行主函數(shù)
數(shù)量不對(duì),那么調(diào)用腳本幫助信息
知識(shí)點(diǎn):
1、腳本參數(shù)數(shù)量判斷
shell內(nèi)置變量: # 條件表達(dá)式: [# -eq 1 ]
2、條件判斷:
雙分支if語(yǔ)句
方案:
1、雙分支if語(yǔ)句 + main函數(shù)調(diào)用

腳本實(shí)施

!/bin/bash

...

執(zhí)行主函數(shù)

if [ # -eq 1 ] then main1
else
usage
fi
8.3腳本調(diào)試功能
我們介紹腳本調(diào)試的時(shí)候呢,主要分三種方式來(lái)介紹:

-n 檢查腳本中的語(yǔ)法錯(cuò)誤
-v 先顯示腳本所有內(nèi)容,然后執(zhí)行腳本,結(jié)果輸出,如果執(zhí)行遇到錯(cuò)誤,將錯(cuò)誤輸出。
-x 將執(zhí)行的每一條命令和執(zhí)行結(jié)果都打印出來(lái)

8.4 生產(chǎn)腳本編寫(xiě)總結(jié)
8.4.1 簡(jiǎn)單腳本編寫(xiě)總結(jié)
1、手工執(zhí)行的命令一定要可執(zhí)行
2、命令簡(jiǎn)單羅列
3、固定的內(nèi)容變量化
4、功能函數(shù)化
8.4.2 復(fù)雜腳本編寫(xiě)總結(jié)
1、手工執(zhí)行的命令一定要可執(zhí)行
2、根據(jù)發(fā)布流程編寫(xiě)腳本的框架
3、將手工執(zhí)行的命令填充到對(duì)應(yīng)的框架函數(shù)內(nèi)部
4、增加日志功能,方便跟蹤腳本歷史執(zhí)行記錄
5、主函數(shù)中邏輯流程控制好
6、設(shè)計(jì)安全的方面:
增加鎖文件,保證代碼發(fā)布的過(guò)程中不受干擾,
輸入?yún)?shù)數(shù)量
輸入?yún)?shù)匹配
腳本幫助信息
7、調(diào)試腳本

8.4.3 注意事項(xiàng):
1、命令一定要保證能正常執(zhí)行
2、成對(duì)的符號(hào),要成對(duì)寫(xiě),避免丟失
3、函數(shù)調(diào)用,
寫(xiě)好函數(shù)后,一定要在主函數(shù)中進(jìn)行調(diào)用
4、避免符號(hào)出現(xiàn)中文
5、命令變量的寫(xiě)法一定要規(guī)范
6、固定的內(nèi)容一定要變量實(shí)現(xiàn),方便以后更改
7、日志的輸出
8、腳本的傳參和函數(shù)的傳參要區(qū)別對(duì)待

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容