shell

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

腳本命名
shell腳本的命名簡單來說就是要有意義,方便我們通過腳本名,來知道這個文件是干什么用的。

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

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

!/bin/bash

echo '1'

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

echo '3'

多行注釋:
多行注釋有兩種方法::<<! ... ! 和 :<<字符 ... 字符

!/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 (強烈推薦使用)
/path/to/script-name 或 ./script-name (當(dāng)前路徑下執(zhí)行腳本)
source script-name 或 . script-name (注意“.“點號)

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

!/bin/bash

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


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

普通變量:
普通變量的定義方式有如下三種,接下來我們就分別說一下這三種方式:

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

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

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

定義方式一:
變量名=命令
注意:
` 是反引號

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

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


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

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

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

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

取消變量
unset 變量名


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

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

!/bin/bash

獲取腳本的名稱

echo "我腳本的名稱是: file.sh"
echo "我腳本的名稱是:$0"

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

!/bin/bash

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

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

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

echo "第一個位置的參數(shù)是: 1" echo "第二個位置的參數(shù)是:2"
echo "第三個位置的參數(shù)是: 3" echo "第四個位置的參數(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

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

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

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

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

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

!/bin/bash

套餐選擇演示

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

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

!/bin/bash

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

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


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

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

操作注意:
[]兩側(cè)為什么要有空格
root@ubuntu:~# [-x /bin/bash ]
[-x: command not found
可以看到:
兩側(cè)沒有空格,就會報錯,為什么呢?因為你不合規(guī)范

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

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

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

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

條件成立

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

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

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

條件不成立

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

文件表達(dá)式

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

[ -f weizhi.sh ] && echo "是一個文件"

是一個文件

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

不是一個文件

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

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

不是一個目錄

mkdir nihao

[ -d nihao ] && echo "是一個目錄"

是一個目錄

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

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

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

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

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

數(shù)值操作符

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

字符串比較

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


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

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

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

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

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

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

符號
作用:
表示將符號左側(cè)的內(nèi)容,以追加的方式輸入到右側(cè)文件的末尾行中
演示:
查看文件內(nèi)容
admin-1@ubuntu:~cat file.txt file1.txt 使用重定向符號給文件中增加內(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 管道符 |
定義:
| 這個就是管道符,傳遞信息使用的

使用格式:
命令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 其他符號
后臺展示符號 &
定義:
& 就是將一個命令從前臺轉(zhuǎn)到后臺執(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

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

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

!/bin/bash

echo '下一條錯誤命令'
dsfsafsafdsa
腳本執(zhí)行效果
admin-1@ubuntu:~# bash ceshi.sh
下一條錯誤命令
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
下一條錯誤命令
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
下一條錯誤命令
ceshi.sh: line 3: dsfsafsafdsa: command not found

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

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

模板文件
admin-1@ubuntu:~cat find.txt nihao aaa nihao AAA NiHao bbb nihao CCC -c: 輸出匹配到aaa的個數(shù) admin-1@ubuntu:~ grep -c aaa find.txt
1
-n: 輸出匹配內(nèi)容,同時顯示行號
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
小技巧:
精確定位錯誤代碼
grep -nr [錯誤關(guān)鍵字] *


3.3.2 sed命令詳解
sed 行文件編輯工具。因為它編輯文件是以行為單位的。
命令格式詳解

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

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

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

常見替換格式:
模板文件內(nèi)容
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)容#' 文件名

示例:替換首每行的第1個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

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

示例:替換第2行的首個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

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

示例:替換每行的第2個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

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

示例:替換第3行的第2個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

增加操作

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

演示效果:
指定行號增加內(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

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

演示效果:
指定行號增加內(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

刪除操作

作用:
指定行號刪除
格式:
sed -i '行號d' 文件名
注意:
如果刪除多行,可以在行號位置多寫幾個行號,彼此間使用逗號隔開,例如
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是一個功能非常強大的文檔編輯工具,它不僅能以行為單位還能以列為單位處理文件。
命令格式:
awk [參數(shù)] '[ 動作]' [文件名]

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

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

常見內(nèi)置變量
FILENAME 當(dāng)前輸入文件的文件名,該變量是只讀的
NR 指定顯示行的行號
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)限來查找文件。
-user 按照文件屬主來查找文件。
-group 按照文件所屬的組來查找文件。
-type 查找某一類型的文件,
諸如:
b - 塊設(shè)備文件 d - 目錄 c - 字符設(shè)備文件
p - 管道文件 l - 符號鏈接文件 f - 普通文件。
-size n:[c] 查找文件長度為n塊的文件,帶有c時表示文件長度以字節(jié)計。
-depth:在查找文件時,首先查找當(dāng)前目錄中的文件,然后再在其子目錄中查找。
-mindepth n:在查找文件時,查找當(dāng)前目錄中的第n層目錄的文件,然后再在其子目錄中查找。
! : 表示取反

命令演示
在當(dāng)前系統(tǒng)中查找一個叫awk的文件
admin-1@ubuntu:~sudo find /home/admin-1/ -name "awk.txt" /home/admin-1/awk.txt 在當(dāng)前系統(tǒng)中查找文件類型為普通文件的文件 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的語句中,流程控制主要分為兩種:
簡單流程控制語句:選擇和循環(huán)
復(fù)雜流程控制語句:函數(shù)
4.1 簡單流程控制語句
4.1.1 單分支if語句
語法格式
if [ 條件 ]
then
指令
fi

場景:
單一條件,只有一個輸出

單分支if語句示例

!/bin/bash

單if語句的使用場景

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

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

雙分支if語句示例

!/bin/bash

單if語句的使用場景

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

多分支if語句示例

!/bin/bash

單if語句的使用場景

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


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

參數(shù)和功能詳情如下:
參數(shù) 執(zhí)行效果
start 服務(wù)啟動中...
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語句的使用場景

if [ "1" == "start" ] then echo "服務(wù)啟動中..." 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選擇語句
我們發(fā)現(xiàn)多if語句使用的時候,代碼量很多,而且整體看起來確實有那么一丁點亂,有沒有辦法更好的實現(xiàn)這種效果呢?就是Case語句。

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

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

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

腳本內(nèi)容:

cat case.sh

!/bin/bash

case語句使用場景

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


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

場景:
遍歷列表

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

示例:遍歷文件

!/bin/bash

for語句的使用示例

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

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

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

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

!/bin/bash

while的示例

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

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

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

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

!/bin/bash

until的示例

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


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

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

!/bin/bash

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

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

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

!/bin/bash

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

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ù)的使用場景二

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

!/bin/bash

定義本地變量

arg="$1"

腳本幫助信息

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

函數(shù)主框架

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

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

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

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

干擾因素多
不安全

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

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


注: 大型腳本流程
5.2.2 流程詳解
接下來我們來對每個過程進(jìn)行一個仔細(xì)的敘述
部署場景:
兩臺主機(jī)做部署動作

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

獲取代碼

代碼倉庫
    集中式的:   svn
    分布式的:   git

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

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

打包代碼
場景演示:

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

傳輸代碼
場景效果:

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

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

解壓代碼:
tar xf ...

放置代碼
為了避免我們在放置代碼過程中,對老文件造成影響,所以我們放置代碼一般分為兩步:備份老文件和放置新文件。
備份原文件

    放置新文件

注意:
    兩個文件的名稱是一樣的,只是內(nèi)容不同
    對整個應(yīng)用項目來說,兩個文件沒有區(qū)別

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

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


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

命令參數(shù)詳解
z 指定壓縮文件的格式為 tar.gz
c 表示壓縮
v 顯示詳細(xì)過程
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)程連接的用戶@遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)的目錄路徑
遠(yuǎn)端主機(jī)文件位置的表示形式:
遠(yuǎn)程連接的用戶@遠(yuǎn)程主機(jī):遠(yuǎn)程主機(jī)的文件路徑

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

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

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

date +%F

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

date +%T

03:06:30

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

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

date +%Y%m%d

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

date +%H%M%S

030643

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

時間戳演示效果:
指定的時間戳格式

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

20170928030742

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


練習(xí)案例:
1、在主機(jī)1上創(chuàng)建一個目錄/data/tar-ceshi/,在目錄里面創(chuàng)建兩個文件,內(nèi)容分別如下:
文件名 內(nèi)容
file1.txt file1
file2.txt file2
2、對目錄tar-ceshi進(jìn)行壓縮
3、對目錄tar-ceshi進(jìn)行時間戳備份
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)境部署這塊,我們需要有一個項目的基礎(chǔ)環(huán)境,然后在這個基礎(chǔ)環(huán)境上,再根據(jù)項目需求搭建一個能讓項目代碼正常運行的環(huán)境。所以這塊的知識,我們從三個方面來學(xué)習(xí)
基礎(chǔ)環(huán)境
方案分析
項目環(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)境
問題:
我們上面進(jìn)行文件傳輸?shù)臅r候,發(fā)現(xiàn)一個問題,每次進(jìn)行文件傳輸都需要進(jìn)行密碼驗證,這對我們來說,有些一丁點不舒服,那么有沒有辦法,讓我痛苦一點?
答案就是:主機(jī)間免密碼認(rèn)證

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

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

方案實施
1、生成秘鑰對
ssh-keygen -t rsa
-t 指定秘鑰的類型
rsa 秘鑰類型

        秘鑰目錄:/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、驗證操作
        ssh root@192.168.8.15
        
    1和5是在8.14上操作
    2-4是在8.15上操作

6.2 方案分析
6.2.1 需求
需求:
部署一個環(huán)境,支持我們的django項目正常運行
6.2.2 需求分析
分析:
2、python環(huán)境 ---> 3、python虛擬環(huán)境
1、django環(huán)境部署
4、django軟件安裝
5、項目基本操作
6、應(yīng)用基本操作
7、view和url配置
8、問題:只有本機(jī)能訪問
9、方案代理---- 10、nginx
11、nginx實現(xiàn)代理
13、pcre軟件安裝
12、nginx軟件安裝
14、nginx基本操作
15、nginx代理的配置
16、目錄結(jié)構(gòu)
17、查看配置文件
18、找到對應(yīng)的代理配置項
19、啟動django
20、啟動nginx
21、整個項目調(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 項目基本操作
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 編輯代理配置項
三、項目調(diào)試
3.1 啟動軟件
3.1.1 啟動django
3.1.2 啟動nginx
3.2 整個項目調(diào)試

6.3 項目環(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

拓展知識點:
python類型軟件的安裝流程
普通:
解壓 安裝
特殊:
解壓 編譯 安裝

        編譯:python setup.py build

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

vim itcast/settings.py

INSTALL_APP = [
。。。
'test1',
]
view和url配置
需求:
訪問django的頁面請求為:127.0.0.1:8000/hello/,頁面返回效果為: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),
]

啟動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

拓展知識點:
linux中軟件安裝的一般流程
解壓
tar
解壓文件,獲取真正的配置文件
配置
configure
根據(jù)默認(rèn)的配置項或者更改配置項,生成編譯配置文件(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簡單操作
檢查
/data/server/nginx/sbin/nginx -t
開啟
/data/server/nginx/sbin/nginx
關(guān)閉
/data/server/nginx/sbin/nginx -s stop
重載
/data/server/nginx/sbin/nginx -s reload

常見問題
突發(fā)問題:
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、先看報錯
        2、思考,是否報錯真實有效
            分析: 誰錯了
            
        3、查找文件
            全名找不到,我們使用正則
        4、找到文件,我沒有問題
            nginx默認(rèn)找?guī)煳募穆窂接袉栴}
        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配置簡介
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)頁文件
│ ├── 50x.html
│ └── index.html
├── logs 日志目錄
│ ├── access.log
│ └── error.log
├── ...
├── sbin 執(zhí)行文件目錄
│ └── nginx
├── ...

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

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

代理是什么?
哥,這事交給我就行了,您就甭操心了。
編輯配置文件實現(xiàn)代理功能
配置內(nèi)容
62: location /hello/ {
63: proxy_pass http://127.0.0.1:8000;
64: }
注釋:
當(dāng)我訪問地址是
配置文件生效
/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)用
    解壓代碼
    放置代碼
        備份老文件

        放置新文件

    開啟應(yīng)用
    檢查

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

7.2 方案實施
獲取代碼
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

注意:
前面兩步在代碼倉庫主機(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)程號,
        lsof -Pti :8000
    殺死進(jìn)程號
        kill 56502

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

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

放置代碼
備份老文件
需求:備份的格式:
文件名-時間戳
時間戳:年月日時分秒
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/

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

檢查
netstat -tnulp | grep ':80'


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

實現(xià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
腳本編寫完成后,進(jìn)行測試:
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)容變量化
問題:
腳本里面的手寫的固定的內(nè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}"
腳本編寫完成后,進(jìn)行測試:
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ù)化
需求:
三條命令其實是一個組合,實現(xiàn)的是一個功能
腳本優(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
腳本編寫完成后,進(jìn)行測試:
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ī)登錄用戶名@遠(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í)行腳本測試
遠(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 大型腳本編寫
本地是指線上服務(wù)器主機(jī)(192.168.8.14)
我們先來回顧一下代碼發(fā)布流程圖
編寫大型腳本有一個流程:
一、腳本框架
二、命令填充
三、完善功能
增加日志功能
增加鎖文件功能
增加主函數(shù)邏輯
增加參數(shù)安全措施

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

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

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

腳本實施:

!/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 "放置新文件"
}

開啟應(yīng)用

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

檢查

check(){
echo "檢查項目"
}

部署函數(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í)行完整的代碼部署過程
方案:
在腳本框架中,填寫執(zhí)行成功的命令

腳本實施:

!/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/
}

開啟應(yīng)用

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

檢查

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

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

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

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

腳本實施:

!/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 "放置新文件"
}

開啟應(yīng)用

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

檢查

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

...

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

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

2、存在鎖文件時候,輸出報錯信息
3、腳本執(zhí)行的時候,需要創(chuàng)建鎖文件
4、腳本執(zhí)行結(jié)束的時候,需要刪除鎖文件

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

腳本實施

!/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
}

腳本報錯信息

err_msg(){
echo "腳本 $0 正在運行,請稍候..."
}

主函數(shù)

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

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

main

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

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

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

腳本實施

!/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)化
需求:
對腳本傳入的參數(shù)的數(shù)量進(jìn)行判斷,如果參數(shù)數(shù)量不對,提示腳本的使用方式,然后退出

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

腳本實施

!/bin/bash

...

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

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

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

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

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

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

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

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