shell

第 2 章 SHELL 基礎(chǔ)知識
2.1 shell腳本
我們在上面簡單介紹了一下什么是shell腳本不狮,現(xià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í)行通尘却蓿可以采用以下幾種方式

bash /path/to/script-name 或 /bin/bash /path/to/script-name (強烈推薦使用)
/path/to/script-name 或 ./script-name (當前路徑下執(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)境和當前用戶環(huán)境一致仙蛉。
使用頻率:☆☆☆
使用場景:環(huán)境一致性
2.1.2 腳本開發(fā)規(guī)范
1笋敞、腳本命名要有意義,文件后綴是.sh
2荠瘪、腳本文件首行是而且必須是腳本解釋器

!/bin/bash

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


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

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

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

習慣:
數(shù)字不加引號,其他默認加雙引號

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

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

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

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


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

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

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

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

取消變量
unset 變量名


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

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

!/bin/bash

獲取腳本的名稱

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

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

!/bin/bash

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

echo "當前腳本傳入的參數(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個字符

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

格式:
    ${變量名:-默認值}

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

!/bin/bash

套餐選擇演示

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

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

!/bin/bash

默認值演示示例二

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


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

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

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

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

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

&&
命令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 "條件不成立"

文件表達式

-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 計算表達式
定義:
計算表達式,簡單來說就是對具體的內(nèi)容進行算數(shù)計算

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

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

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

let演示效果
格式:let 變量名a=變量名a+1
注意:
表達式必須是一個整體,中間不能出現(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使用

命令演示:
查看當前系統(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 代表所有輸出的信息
符號示例
標準正確輸出示例
cat nihao.txt 1>> zhengque
標準錯誤輸出示例
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的操作效果业簿,實際上不對文件進行編輯
-i 表示對文件進行編輯
注意: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)于替換矾湃,我們從三個方面來學習:
行號亡脑、列號、全體
命令格式:
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

作用:
在指定行號的當行增加內(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 顯示當前行所有內(nèi)容n 顯示當前行的第n列內(nèi)容,如果存在多個$n粉私,它們之間使用逗號(,)隔開

常見內(nèi)置變量
FILENAME 當前輸入文件的文件名顽腾,該變量是只讀的
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:在查找文件時酥诽,首先查找當前目錄中的文件,然后再在其子目錄中查找皱埠。
-mindepth n:在查找文件時肮帐,查找當前目錄中的第n層目錄的文件,然后再在其子目錄中查找边器。
! : 表示取反

命令演示
在當前系統(tǒng)中查找一個叫awk的文件
admin-1@ubuntu:~sudo find /home/admin-1/ -name "awk.txt" /home/admin-1/awk.txt 在當前系統(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)
復雜流程控制語句:函數(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ǔ)上對腳本進行升級
需求:
要求腳本執(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ù)相同,當循環(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
注意:
條件的類型:
命令搪泳、[[ 字符串表達式 ]]、(( 數(shù)字表達式 ))

場景:
只要條件滿足扼脐,就一直循環(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
注意:
條件的類型:
命令岸军、[[ 字符串表達式 ]]、(( 數(shù)字表達式 ))

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

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

!/bin/bash

until的示例

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


4.2 復雜流程控制語句
函數(shù)就是我們的復雜流程控制語句
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ù)量卒废、條件表達式(驗證+數(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)在為止我們學會了多個開發(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機房整陌、阿里云、亞馬遜瞎领、騰訊云泌辫、華為云、....
發(fā)布的效果九默?
web網(wǎng)頁對外展示

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

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

干擾因素多
不安全

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

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


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

注意:
部署的文件就是兩臺主機右上角的紅色內(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)閉離客戶遠的

解壓代碼:
tar xf ...

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

    放置新文件

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

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

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


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

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

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

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

    將本地文件推送到遠程主機
        scp python.tar.gz root@192.168.8.15:/root/
    將遠程主機的文件拉取到本地
        scp root@192.168.8.15:/root/python.tar.gz ./

遠端主機文件放置位置的表示形式:
遠程連接的用戶@遠程主機:遠程主機的目錄路徑
遠端主機文件位置的表示形式:
遠程連接的用戶@遠程主機:遠程主機的文件路徑

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

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

演示效果:
顯示當前日期

date +%F

2017-09-28
顯示當前時間

date +%T

03:06:30

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

演示效果:
顯示當前日期

date +%Y%m%d

20170928
顯示當前時間

date +%H%M%S

030643

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

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

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

20170928030742

備份命令效果格式:
方式一:復制備份
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)驗證操作抡柿,我們確定采用方式二:


練習案例:
1、在主機1上創(chuàng)建一個目錄/data/tar-ceshi/等恐,在目錄里面創(chuàng)建兩個文件洲劣,內(nèi)容分別如下:
文件名 內(nèi)容
file1.txt file1
file2.txt file2
2、對目錄tar-ceshi進行壓縮
3课蔬、對目錄tar-ceshi進行時間戳備份
4囱稽、將壓縮包文件傳輸?shù)竭h端主機2
5、在主機2上解壓 壓縮包文件
6二跋、在主機2上修改壓縮包文件內(nèi)容战惊。然后再次壓縮
7、在主機1上拉取主機2的壓縮包文件
8同欠、使用命令查看壓縮包文件的內(nèi)容
命令執(zhí)行效果:
主機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
主機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
主機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)境莫杈。所以這塊的知識互例,我們從三個方面來學習
基礎(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 主機網(wǎng)絡(luò)環(huán)境
問題:
我們上面進行文件傳輸?shù)臅r候,發(fā)現(xiàn)一個問題筝闹,每次進行文件傳輸都需要進行密碼驗證媳叨,這對我們來說,有些一丁點不舒服关顷,那么有沒有辦法糊秆,讓我痛苦一點?
答案就是:主機間免密碼認證

知識點:
什么是主機間免密碼認證议双?
就是我和另外一臺主機做任何事情痘番,不需要輸入密碼認證,非常很方便平痰。

方案詳解
我們要做主機間免密碼認證需要做三個動作
1汞舱、本機生成密鑰對
2、對端機器使用公鑰文件認證
3觉增、驗證

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

        秘鑰目錄:/root/.ssh/
            私鑰      id_rsa                  鑰匙
            公鑰      id_rsa.pub          鎖
            
    2、編輯認證文件
        admin-1@ubuntu:~/.ssh# cat /root/.ssh/authorized_keys 
        ssh-rsa AAAAB3N...PVp admin-1@ubuntu
        注意:
            認證文件內(nèi)容和8.15機器的公鑰文件內(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墙杯、問題:只有本機能訪問
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
進入
source venv/bin/activate
退出
deactivate
刪除
rm -rf venv
6.3.2 django環(huán)境
django軟件安裝
注意:先進入虛擬環(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ù)默認的配置項或者更改配置項硫狞,生成編譯配置文件(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默認找?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 默認的配置文件
│ ...
├── ...
├── 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: }
注釋:
當我訪問地址是
配置文件生效
/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)用
    檢查

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

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

注意:
前面兩步在代碼倉庫主機上操作

傳輸代碼
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ù)端口查看進程號,
        lsof -Pti :8000
    殺死進程號
        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ā)布代碼部分呢,我們將這個代碼部署流程拆分成兩部分:簡單腳本(遠端主機上執(zhí)行)和大型腳本(線上機器執(zhí)行)癣猾,這樣我們能從兩個方面來學習生產(chǎn)中的腳本如何編寫敛劝。首先來說簡單腳本的編寫
8.1 簡單腳本編寫
簡單腳本我們從四個方面來學習:
1、命令羅列實現(xiàn)功能
2纷宇、固定內(nèi)容變量實現(xiàn)
3攘蔽、功能函數(shù)實現(xiàn)
4、遠程執(zhí)行命令
8.1.1 命令羅列
目的:
實現(xiàn)代碼倉庫主機上的操作命令功能即可

實現(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
腳本編寫完成后呐粘,進行測試:
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}"
腳本編寫完成后转捕,進行測試:
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
腳本編寫完成后,進行測試:
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 遠程執(zhí)行
遠程命令執(zhí)行
格式:
ssh 遠程主機登錄用戶名@遠程主機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
...

遠程執(zhí)行腳本測試
遠程更新文件內(nèi)容
ssh root@192.168.8.15 "sed -i /'s#1.4#1.5#' /data/codes/django/views.py"
遠程查看腳本
ssh root@192.168.8.15 "ls /data/scripts"
遠程執(zhí)行腳本
ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh"
遠程檢查更新效果
ssh root@192.168.8.15 "zcat /data/codes/django.tar.gz"
8.2 大型腳本編寫
本地是指線上服務(wù)器主機(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語句
文件表達式: -f file_name
驗證表達式: [ 表達式 ]
創(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)部進行調(diào)用參數(shù)
2犀农、腳本的幫助信息
3、腳本內(nèi)容就需要對傳參的內(nèi)容進行判斷

知識點:
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ù)進行匹配
如果傳入?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ù)量進行判斷石景,如果參數(shù)數(shù)量不對捍歪,提示腳本的使用方式,然后退出

分析:
1鸵钝、腳本參數(shù)數(shù)量判斷
2糙臼、條件判斷
數(shù)量對,那么執(zhí)行主函數(shù)
數(shù)量不對恩商,那么調(diào)用腳本幫助信息
知識點:
1变逃、腳本參數(shù)數(shù)量判斷
shell內(nèi)置變量: # 條件表達式: [# -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 復雜腳本編寫總結(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ù)中進行調(diào)用
4叠聋、避免符號出現(xiàn)中文
5、命令變量的寫法一定要規(guī)范
6受裹、固定的內(nèi)容一定要變量實現(xiàn)碌补,方便以后更改
7、日志的輸出
8棉饶、腳本的傳參和函數(shù)的傳參要區(qū)別對待

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厦章,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子照藻,更是在濱河造成了極大的恐慌袜啃,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幸缕,死亡現(xiàn)場離奇詭異群发,居然都是意外死亡,警方通過查閱死者的電腦和手機发乔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門熟妓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人栏尚,你說我怎么就攤上這事起愈。” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵告材,是天一觀的道長坤次。 經(jīng)常有香客問我,道長斥赋,這世上最難降的妖魔是什么缰猴? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮疤剑,結(jié)果婚禮上滑绒,老公的妹妹穿的比我還像新娘。我一直安慰自己隘膘,他們只是感情好疑故,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弯菊,像睡著了一般纵势。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上管钳,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天钦铁,我揣著相機與錄音,去河邊找鬼才漆。 笑死牛曹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的醇滥。 我是一名探鬼主播黎比,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸳玩!你這毒婦竟也來了阅虫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤不跟,失蹤者是張志新(化名)和其女友劉穎书妻,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躬拢,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡躲履,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了聊闯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片工猜。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖菱蔬,靈堂內(nèi)的尸體忽然破棺而出篷帅,到底是詐尸還是另有隱情史侣,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布魏身,位于F島的核電站惊橱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏箭昵。R本人自食惡果不足惜税朴,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望家制。 院中可真熱鬧正林,春花似錦、人聲如沸颤殴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涵但。三九已至杈绸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矮瘟,已是汗流浹背瞳脓。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芥永,地道東北人篡殷。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓钝吮,卻偏偏與公主長得像埋涧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奇瘦,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

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