自動化運維(DEVOPS)shell
1. shell基礎知識
1.1 shell 腳本
1.1.1 創建腳本
腳本創建工具:
創建腳本的常見編輯器是 vi/vim.
腳本命名
shell腳本的命名簡單來說就是要有意義,方便我們通過腳本名,來知道這個文件是干什么用的。
腳本內容:
各種可以執行的命令
注釋內容:
單行注釋:
除了首行的#不是注釋外,其他所有行內容,只要首個字符是#,那么就表示該行是注釋
#!/bin/bash
echo '1'
# echo '2' # 這一行就表示注釋
echo '3'
多行注釋:
多行注釋有兩種方法::<<! ... ! 和 :<<字符 ... 字符
#!/bin/bash
echo '1'
:<<! echo '2'
echo '3'
echo '4'
!
echo '5'
1.1.2 腳本執行
shell 執行的方式
Shell腳本的執行通常可以采用以下幾種方式
bash /path/to/script-name 或 /bin/bash /path/to/script-name (強烈推薦使用)
/path/to/script-name 或 ./script-name (當前路徑下執行腳本,權限不夠 chmod +x script-name ,ls script-name 查看文件的狀態,變綠表示可執行)
source script-name 或 . script-name (注意“.“點號)
1.1.3. 腳本開發規范
1、腳本命名要有意義,文件后綴是.sh
2、腳本文件首行是而且必須是腳本解釋器
#!/bin/bash
3、腳本文件解釋器后面要有腳本的基本信息等內容
腳本文件中盡量不用中文注釋;
盡量用英文注釋,防止本機或切換系統環境后中文亂碼的困擾
常見的注釋信息:腳本名稱、腳本功能描述、腳本版本、腳本作者、聯系方式等
4、腳本文件常見執行方式:bash 腳本名
5、腳本內容執行:從上到下,依次執行
6、代碼書寫優秀習慣;
1)成對內容的一次性寫出來,防止遺漏。
如:()、{}、[]、''、``、""
2)[]中括號兩端要有空格,書寫時即可留出空格[ ],然后再退格書寫內容。
3)流程控制語句一次性書寫完,再添加內容
7、通過縮進讓代碼易讀;(即該有空格的地方就要有空格)
1.2 shell 變量
普通變量
var=nihao
var1='nihao 666'
var2="use $var1" # 可編譯內部變量
# 字符串拼接
name="Shell"
url="http://c.biancheng.net/shell/"
str1=$name$url #中間不能有空格
str2="$name $url" #如果被雙引號包圍,那么中間可以有空格
str3=$name": "$url #中間可以出現別的字符串
str4="$name: $url" #這樣寫也可以
str5="${name}Script: ${url}index.html" #這個時候需要給變量名加上大括號
echo $str1 #Shellhttp://c.biancheng.net/shell/
echo $str2 #Shell http://c.biancheng.net/shell/
echo $str3 #Shell: http://c.biancheng.net/shell/
echo $str4 #Shell: http://c.biancheng.net/shell/
echo $str5 #ShellScript: http://c.biancheng.net/shell/index.html
對於str1所在行代碼,$name 和 $url 之間之所以不能出現空格,是因為當字符串不被任何一種引號包圍時,遇到空格就認為字符串結束了,空格后邊的內容會作為其他變量或者命令解析,這一點在《Shell字符串》中已經提到。
《Shell字符串》鏈接:http://c.biancheng.net/view/743.html
命令變量
kun2=`pwd`
echo $kun2 # /home/python/Desktop
kun3=$(pwd)
echo $kun3 # /home/python/Desktop
全局變量
env
env | grep execute_command # 查看某個具體的全局變量
export var='var_name' # 創建全局變量
# 例子
export GAN=kuncai123
echo $GAN # kuncai123
echo "my username is ${GAN}" # my username is kuncai123
變量的查看和取消
# 變量的查看
方式一:$變量名
方式二:"$變量名"
方式三:${變量名} # 使用頻率高
方式四:"${變量名}" # 標准使用方式
# 只讀變量
myUrl="http://c.biancheng.net/shell/"
readonly myUrl # 把變量限制為只讀
# 取消變量
unset 變量名 #unset 命令不能刪除只讀變量。
shell 內置變量
符號 意義
$0 獲取當前執行的shell腳本文件名,包括腳本路徑
$n 獲取當前執行的shell腳本的第n個參數值,n=1..9,當n為0時表示腳本的文件名,如果n大於9就要用大 括號括起來${10}
$# 獲取當前shell命令行中參數的總個數
$? 獲取執行上一個指令的返回值(0為成功,非0為失敗)
$$ 表示當前Shell進程的ID,即pid
$* 傳遞給腳本或函數的所有參數。
$@ 傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與 $* 稍有不同,下面將會講到。
# 參考鏈接: http://c.biancheng.net/cpp/view/2739.html
$* 和 $@ 的區別
$* 和 $@ 都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。
但是當它們被雙引號(" ")包含時,"$*" 會將所有的參數作為一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。
python@ubuntu:~/Desktop$ cat inner_var2.sh
#!/bin/bash/
# this is a shell inner variable shell
# $0 獲取當前腳本的文件名
echo "this filename is inner_var.sh"
echo "this filename is $0 "
# $n 獲取第n個參數的位置
echo "第1個位置參數是:$1"
echo "第2個位置參數是:$2"
echo "第3個位置參數是:$3"
echo "第4個位置參數是:$4"
echo "當前Shell進程的ID是: $$"
python@ubuntu:~/Desktop$ bash inner_var2.sh a b c d
this filename is inner_var.sh
this filename is inner_var2.sh
第1個位置參數是:a
第2個位置參數是:b
第3個位置參數是:c
第4個位置參數是:d
當前Shell進程的ID是: 29949
python@ubuntu:~/Desktop$ echo $?
0
字符串精確截取
str='sdwfghrhherth'
python@ubuntu:~/Desktop$ echo ${str::5} # 取前5個
sdwfg
python@ubuntu:~/Desktop$ echo ${str:5} # 取第5個之后的全部
hrhherth
python@ubuntu:~/Desktop$ echo ${str:0-5} # 截取最后5個
herth
python@ubuntu:~/Desktop$ echo ${str:0-6:3} # 取倒數第6個往后截取3個
hhe
默認值相關
#!/bin/bash/
# 這是一個設置變量默認值的測試。
username="$1"
echo "當前用戶名是: ${username:-kuncai}"
marry_age="$2"
echo "國家法定男性結婚年齡是: ${marry_age+22} 歲"
bash var_default_value.sh
當前用戶名是: kuncai
國家法定男性結婚年齡是: 22 歲
bash var_default_value.sh jason 18
當前用戶名是: jason
國家法定男性結婚年齡是: 22 歲
2. shell 進階
2.1 表達式
2.1.1 測試語句
A: test 條件表達式
B: [ 條件表達式 ]
test 1 == 1
echo $? # 0
[ 1 == 2 ]
echo $? # 1
2.1.2 條件表達式
邏輯表達式
常見的邏輯表達式有: && 和 ||
命令1 && 命令2
如果命令1執行成功,那么我才執行命令2 -- 夫唱婦隨
如果命令1執行失敗,那么命令2也不執行
命令1 || 命令2
如果命令1執行成功,那么命令2不執行 -- 對着干
如果命令1執行失敗,那么命令2執行
# [ 1 = 1 ] && echo "條件成立"
條件成立
# [ 1 = 2 ] && echo "條件成立" # 前者執行失敗,后者不執行,不輸出
# [ 1 = 2 ] || echo "條件不成立"
條件不成立
# [ 1 = 1 ] || echo "條件不成立" # 前者執行成功,后者不執行,不輸出
文件表達式
-f 判斷輸入內容是否是一個文件
-d 判斷輸入內容是否是一個目錄
-x 判斷輸入內容是否可執行
# [ -f weizhi.sh ] && echo "是一個文件"
是一個文件
# [ -f weizhi.sddh ] || echo "不是一個文件"
不是一個文件
# [ -d weizhi.sddh ] || echo "不是一個目錄"
不是一個目錄
# mkdir nihao
# [ -d nihao ] && echo "是一個目錄"
是一個目錄
# [ -x age.sh ] || echo "文件沒有執行權限"
文件沒有執行權限
# [ -x test.sh ] && echo "文件有執行權限"
文件有執行權限
數值操作符
主要根據給定的兩個值,判斷第一個與第二個數的關系,如是否大於、小於、等於第二個數。常見選項如下:
n1 -eq n2 相等
n1 -gt n2 大於
n1 -lt n2 小於
n1 -ne n2 不等於
字符串比較
str1 == str2 str1和str2字符串內容一致
str1 != str2 str1和str2字符串內容不一致,!表示相反的意思
實踐
判斷字符是否內容一致
2.1.3 計算表達式
方式一:
$(()) $(( 計算表達式 ))
方式二:
let let 計算表達式
echo $((100/5))
20
let i=1 i=i+2 && echo $i
3
2.2 linux常見符號
2.2.1 重定向符號
> 表示將符號左側的內容,以覆蓋的方式輸入到右側文件中
>> 表示將符號左側的內容,以追加的方式輸入到右側文件的末尾行中
echo 'hello world' > file.txt
cat file.txt
'hello world'
cp file.txt file1.txt
echo 'hello shell' >> file.txt
'hello world'
'hello shell'
cat file1.txt >> file.txt # 追加其它文件內容到本文件
'hello world'
'hello shell'
'hello world'
2.2.2 管道符
命令1 | 命令2
管道符左側命令1 執行后的結果,傳遞給管道符右側的命令2使用
env | grep SHELL
ps aux | grep 進程名 # 查看進程
2.2.3 其他符號
-
后台展示符號 &
& 就是將一個命令從前台轉到后台執行 sleep 10 & ps aux | grep sleep -
全部信息符號 2>&1
符號詳解: 1 表示正確輸出的信息 2 表示錯誤輸出的信息 2>&1 代表所有輸出的信息 腳本內容 test2.sh #!/bin/bash echo '下一條錯誤命令' dsfs 腳本執行結果 bash test2.sh 下一條錯誤命令 test2.sh: line 3: dsfs: command not found bash test2.sh 1>> test_log 2>> test_log # 上下效果相同 bash test2.sh >> test_log 2>&1 linux系統垃圾桶 /dev/null 是linux下的一個設備文件, 這個文件類似於一個垃圾桶,特點是:容量無限大
2.3 常用命令詳解
2.3.1 grep命令詳解
grep命令是我們常用的一個強大的文本搜索命令。
命令格式詳解
grep [參數][關鍵字] <文件名>
注意:
我們在查看某個文件的內容的時候,是需要有<文件名>
grep命令在結合|(管道符)使用的情況下,后面的<文件名>是沒有的
可以通過 grep --help 查看grep的幫助信息
參數詳解
-c:只輸出匹配行的計數。
-n:顯示匹配行及行號。
-v:顯示不包含匹配文本的所有行。
vim find.txt
# 新建並編輯文件
nihao aaa
nihao AAA
NiHao bbb
nihao CCC
grep -c aaa find.txt # 輸出aaa的匹配行數
1
grep -n CCC find.txt # 輸出匹配內容,同時顯示行號
4:nihao CCC
grep -nv ni find.txt # 輸出不匹配的內容及行號
NiHao bbb
精確定位錯誤代碼
grep -nr [錯誤關鍵字] 文件名 # 快速定位 文本中的錯位關鍵字信息
eg: grep -nr 'keywords' 文件路徑
2.3.2 sed命令詳解
sed 行文件編輯工具。因為它編輯文件是以行為單位的。
命令格式詳解
命令格式:
sed [參數] '<匹配條件> [動作]' [文件名]
注意:
可以通過 sed --help 查看sed的幫助信息
參數詳解:
參數為空 表示sed的操作效果,實際上不對文件進行編輯
-i 表示對文件進行編輯
注意:mac版本的bash中使用 -i參數,必須在后面單獨加個東西: -i ''
匹配條件:
匹配條件分為兩種:數字行號或者關鍵字匹配
關鍵字匹配格式:
'/關鍵字/'
注意:
隔離符號 / 可以更換成 @、#、!等符號
根據情況使用,如果關鍵字和隔離符號有沖突,就更換成其他的符號即可。
動作詳解
-a 在匹配到的內容下一行增加內容
-i 在匹配到的內容上一行增加內容
-d 刪除匹配到的內容
-s 替換匹配到的內容
注意:
上面的動作應該在參數為-i的時候使用,不然的話不會有效果
替換命令
關於替換,我們從三個方面來學習:
行號、列號、全體
命令格式:
sed -i [替換格式][文件名]
注意:替換命令的寫法
's###' ---> 's#原內容##' ---> 's#原內容#替換后內容#'
admin-1@ubuntu:~$ cat sed.txt
nihao sed sed sed
nihao sed sed sed
nihao sed sed sed
sed -i '1,3s#sed#SED#2' sed.txt
cat sed.txt
nihao sed SED sed
nihao sed sed sed
nihao sed SED sed
增加操作
方式1 -- 追加
sed -i '行號a\增加的內容' 文件名
在指定行號的下一行增加內容
方式2 -- 插入
sed -i '行號i\增加的內容' 文件名
注意:
如果增加多行,可以在行號位置寫個范圍值,彼此間使用逗號隔開,例如
sed -i '1,3a\增加內容' 文件名
cat sed.txt
nihao sed SED sed
nihao sed sed sed
nihao sed SED sed
sed '2a\append new line' sed.txt # 注意沒加 -i 不改變原數據結構
nihao sed SED sed
nihao sed sed sed
append new line
nihao sed SED sed
sed '2i\insert new line' sed.txt
nihao sed SED sed
insert new line
nihao sed sed sed
nihao sed SED sed
刪除操作
指定行號刪除
sed -i '行號d' 文件名
如果刪除多行,可以在行號位置多寫幾個行號,彼此間使用逗號隔開,例如
sed -i '1,3d' 文件名
sed -i '2d' sed.txt # 刪除第2行
cat sed.txt
nihao sed SED sed
nihao sed sed sed
2.3.3 awk命令詳解
awk是一個功能非常強大的文檔編輯工具,它不僅能以行為單位還能以列為單位處理文件。
命令格式:
awk [參數] '[ 動作]' [文件名]
常見參數:
-F 指定行的分隔符
常見動作:
print 顯示內容
$0 顯示當前行所有內容
$n 顯示當前行的第n列內容,如果存在多個$n,它們之間使用逗號(,)隔開
常見內置變量
FILENAME 當前輸入文件的文件名,該變量是只讀的
NR 指定顯示行的行號
NF 輸出 最后一列的內容
OFS 輸出格式的列分隔符,缺省是空格
FS 輸入文件的列分融符,缺省是連續的空格和Tab
python@ubuntu:~/Desktop$ cat awk.txt
nihao1 sed sed sed
nihao2 sed sed sed
nihao3 sed sed sed
nihao4 sed sed sed
python@ubuntu:~/Desktop$ awk 'NR==1 {print $1,$3}' awk.txt # 打印第1行 第1,3列
nihao1 sed
python@ubuntu:~/Desktop$ sed -i 's# #:#g' awk.txt
cat awk.txt
nihao1:sed:sed:sed
nihao2:sed:sed:sed
nihao3:sed:sed:sed
nihao4:sed:sed:sed
python@ubuntu:~/Desktop$ awk -F ':' '{print $1,$3}' awk.txt
nihao1 sed
nihao2 sed
nihao3 sed
nihao4 sed
python@ubuntu:~/Desktop$ awk 'BEGIN{OFS=":"} {print NR,$0}' sed.txt
1:nihao1 sed sed sed
2:nihao2 sed sed sed
3:nihao3 sed sed sed
4:nihao4 sed sed sed
2.3.4 find命令詳解
命令格式:
find [路徑][參數] [關鍵字]
參數詳解
-name 按照文件名查找文件。
-perm 按照文件權限來查找文件。
-user 按照文件屬主來查找文件。
-group 按照文件所屬的組來查找文件。
-type 查找某一類型的文件,
諸如:
b - 塊設備文件 d - 目錄 c - 字符設備文件
p - 管道文件 l - 符號鏈接文件 f - 普通文件。
-size n:[c] 查找文件長度為n塊的文件,帶有c時表示文件長度以字節計。
-depth:在查找文件時,首先查找當前目錄中的文件,然后再在其子目錄中查找。
-mindepth n:在查找文件時,查找當前目錄中的第n層目錄的文件,然后再在其子目錄中查找。
! : 表示取反
find /home -type d -name 'conda*'
find /home -type f -name 'test'
3. 流程控制
3.1 簡單流程控制語句
3.1.1 if 語句
# 使用語法
if [ 條件 ]
then
指令1
elif [ 條件2 ]
then
指令2
else
指令3
fi
python@ubuntu:~/Desktop$ vim if2.sh
#編輯腳本
#!/bin/bash
# 多if語句的使用場景
if [ "$1" == "start" ]
then
echo "服務啟動中..."
elif [ "$1" == "stop" ]
then
echo "服務關閉中..."
elif [ "$1" == "restart" ]
then
echo "服務重啟中..."
else
echo "$0 腳本的使用方式: $0 [ start | stop | restart ]"
fi
# 執行腳本
python@ubuntu:~/Desktop$ bash if2.sh restart
服務重啟中...
python@ubuntu:~/Desktop$ bash if2.sh start
服務啟動中...
python@ubuntu:~/Desktop$ bash if2.sh stop
服務關閉中...
python@ubuntu:~/Desktop$ bash if2.sh stop22
if2.sh 腳本的使用方式: if2.sh [ start | stop | restart ]
3.1.2 case選擇語句
case 變量名 in
值1)
指令1
;;
值2)
指令2
;;
值3)
指令3
;;
esac
python@ubuntu:~/Desktop$ vim case.sh
# 編輯腳本
#!/bin/bash
# 這是case語句使用場景的測試
case "$1" in
"start")
echo "service is starting"
;;
"stop")
echo "service is stoping"
;;
"restart")
echo "service is restarting"
;;
*)
echo "$0 correct using way is: $0 [ start|stop|restart ]"
;;
esac
# 執行腳本
python@ubuntu:~/Desktop$ bash case.sh start
service is starting
python@ubuntu:~/Desktop$ bash case.sh stop
service is stoping
python@ubuntu:~/Desktop$ bash case.sh restart
service is restarting
python@ubuntu:~/Desktop$ bash case.sh restart2
case.sh the script correct using way is: case.sh [ start|stop|restart ]
3.1.3 for 循環語句
for 值 in 列表
do
執行語句
done
ps:如果需要手動構建列表,比列表[a1,b2,c3]則可以寫成 for i in {a1,b2,c3} do; ... done
另外就是列表中只有一個值,后面的逗號也不能省略;
python@ubuntu:~/Desktop$ vim for.sh
# 編輯腳本
#!/bin/bash
# for語句使用場景測試
cpath=$(pwd)
for i in $(ls $cpath)
do
echo "$cpath 目錄下包含文件${i}"
done
# 執行腳本
python@ubuntu:~/Desktop$ bash for.sh
/home/python/Desktop 目錄下包含文件case.sh
/home/python/Desktop 目錄下包含文件for.sh
/home/python/Desktop 目錄下包含文件hive簡介.png
/home/python/Desktop 目錄下包含文件if2.sh
/home/python/Desktop 目錄下包含文件if.sh
/home/python/Desktop 目錄下包含文件inner_var2.sh
3.1.4 while循環語句
while 條件
do
執行語句
done
條件的類型: 命令、[[ 字符串表達式 ]]、(( 數字表達式 ))
python@ubuntu:~/Desktop$ vim while.sh
# 編輯腳本
#!/bin/bash
# while循環語句測試
a=1
while [ "${a}" -lt 5 ]
do
echo "${a}"
a=$((a+1))
done
# 執行腳本
python@ubuntu:~/Desktop$ bash while.sh
1
2
3
4
3.1.5 until循環語句
until 條件
do
執行語句
done
條件的類型: 命令、[[ 字符串表達式 ]]、(( 數字表達式 ))
停止條件正好和while相反,只要條件不滿足,就一直循環下去
python@ubuntu:~/Desktop$ vim until.sh
# 編輯腳本
#!/bin/bash
# until循環語句測試
a=1
until [ "${a}" -eq 5 ]
do
echo "${a}"
a=$((a+1))
done
# 執行腳本
python@ubuntu:~/Desktop$ bash until.sh
1
2
3
4
3.2 復雜流程控制語句
3.2.1 函數
函數就是將某些命令組合起來實現某一特殊功能的方式,是腳本編寫中非常重要的一部分。
傳參函數格式:
傳參數
函數名 參數
函數體調用參數:
注意:
類似於shell內置變量中的位置參數
函數名( ){
函數體 $n
}
python@ubuntu:~/Desktop$ vim func.sh
# 編輯腳本
#!/bin/bash
# 函數定義及調用
print2(){
echo "this is just a function test !"
}
print2
# 函數傳參演示
print3(){
echo "my name is $1"
echo "your name is $2"
}
print3 "$1" "$2"
# 執行腳本
python@ubuntu:~/Desktop$ bash func.sh jason judy
this is just a function test !
my name is jason
your name is judy
3.3 綜合案例
需求
1、zonghe.sh 腳本執行時候需要添加參數才能執行
參數和功能詳情如下:
參數 執行效果
start 服務啟動中...
stop 服務關閉中...
restart 服務重啟中...
* 腳本幫助信息...
2、參數的數量有限制,只能是1個,多余一個會提示腳本的幫助信息
3、幫助信息使用函數來實現
信息內容:腳本 zonghe.sh 使用方式 zonghe.sh [ start|stop|restart ]
代碼實踐
python@ubuntu:~/Desktop$ vim zonghe.sh
# 編輯腳本
#!/bin/bash
# 注意{}中一定要換行,不然語法報錯!
helpinfo(){
echo "腳本$0 使用方式是: $0 [ start|stop|restart ]"
}
# 先編寫主結構
if [ $# -eq 1 ] # 如果參數數量是1個
then
# 這是case語句使用場景的測試
case "$1" in
"start")
echo "service is starting"
;;
"stop")
echo "service is stoping"
;;
"restart")
echo "service is restarting"
;;
*)
helpinfo
;;
esac
else
helpinfo
fi
# 執行腳本
python@ubuntu:~/Desktop$ bash zonghe.sh start 2
腳本zonghe.sh 使用方式是: zonghe.sh [ start|stop|restart ]
python@ubuntu:~/Desktop$ bash zonghe.sh start
service is starting
python@ubuntu:~/Desktop$ bash zonghe.sh stop2
腳本zonghe.sh 使用方式是: zonghe.sh [ start|stop|restart ]
4. 代碼發布
代碼發布流程圖
![代碼發布流程圖]](https://img2020.cnblogs.com/blog/1563359/202004/1563359-20200429190824006-748254772.png)
**文件的壓縮和解壓**
文件的壓縮
壓縮格式:
tar zcvf 壓縮后的文件名 將要壓縮的文件
文件的解壓
解壓格式:
tar xf 壓縮后的文件名 -C 解壓后的路徑
命令參數詳解
z 指定壓縮文件的格式為 tar.gz
c 表示壓縮
v 顯示詳細過程
f 指定壓縮文件
x 解壓
查看壓縮文件內容
zcat 壓縮文件
**文件的傳輸**
將本地文件推送到遠程主機
scp script.tar.gz root@192.168.8.15:/root/
將遠程主機的文件拉取到本地
scp root@192.168.8.15:/root/script.tar.gz ./
win10本機 --> ubuntu
scp city80.txt python@192.168.5.137:/home/python/Desktop
ubuntu 本機-->win10
scp city80.txt 15583@172.16.14.152:
直接拷貝文件到了 C:\User\15583 目錄下
**文件的備份**
方式一:復制備份
cp script script-$(date +%Y%m%d%H%M%S)
方式二:移動備份
mv script script-$(date +%Y%m%d%H%M%S)
python@ubuntu:~/Desktop$ ls
script
# 壓縮文件
python@ubuntu:~/Desktop$ tar zcf script.tar.gz script/
python@ubuntu:~/Desktop$ ls
script script.tar.gz
# 移動備份文件
python@ubuntu:~/Desktop$ mv script script-$(date +%Y%m%d%H%M%S)
python@ubuntu:~/Desktop$ ls
script-20190520121245 script.tar.gz
# 解壓壓縮文件
python@ubuntu:~/Desktop$ tar zxf script.tar.gz
python@ubuntu:~/Desktop$ ls
script script.tar.gz script-20190520121245
5. 環境部署
mkdir /data/{server,logs,backup,softs,virtual,scripts,codes} -p
# 虛擬環境搭建的兩種方式
# 方式1--這種默認安裝的是python2.x版本的,不推薦。
sudo pip3 install virtualenvs
sudo apt-get install virtualenvs
sudo apt-get install virtualenvswrapper
# 創建虛擬環境
mkvirtualenv -p python3 環境名稱 # 不指定python版本,則默認是2.x版本
workon 環境名稱 # 進入虛擬環境
pip install flask==0.10.1 # 指定版本安裝flask
# 方式2
apt-get install python-virtualenv -y
# /media/python/myfiles/.virtualenvs
virtualenv -p /home/python/anaconda3/bin/python3.7 kun
source kun/bin/activate
# 安裝django包
cd /media/python/myfiles/data/softs/Django-1.10.7
python setup.py install
# 創建django項目
cd .../data/server
django-admin startproject midou
# 創建應用
cd .../data/server/miduo
django-admin startapp user
# python manage.py startapp user
# 注冊應用
# vim midou/settings.py
33 INSTALLED_APPS = [
34 'django.contrib.admin',
35 'django.contrib.auth',
36 'django.contrib.contenttypes',
37 'django.contrib.sessions',
38 'django.contrib.messages',
39 'django.contrib.staticfiles',
40 'user',
41 ]
# view和url配置
vim user/views.py
1 from django.shortcuts import render
2 from django.http import HttpResponse
3
4 # Create your views here.
5
6 def hello(request):
7 return HttpResponse("midou V1.0")
vim midou/urls.py
16 from django.conf.urls import url
17 from django.contrib import admin
18
19 from user.views import *
20
21 urlpatterns = [
22 url(r'^admin/', admin.site.urls),
23 url(r'^hello/$', hello),
# 啟動django
python manage.py runserver
python manage.py runserver >> /dev/null 2>&1 &
訪問 http://127.0.0.1:8000/hello/
輸出 midou V1.0
# 安裝pcre包
# 解壓壓縮包
cd .../data/softs
tar zxf pcre-8.39.tar.gz
cd pcre-8.39
# 配置 -- 根據默認的配置項或者更改配置項,生成編譯配置文件(Makefile)
./configure
# 編譯 -- 根據 Makefile 內容,編譯生成指定的軟件所需要的所有文件
make
# 安裝 -- 將編譯生成的所有文件,轉移到指定安裝的目錄下面 --prefix
sudo make install
# 安裝ngix包
# 解壓壓縮包
cd .../data/soft/
tar zxf nginx-1.10.2.tar.gz
# 配置
cd nginx-1.10.2/
./configure --prefix=/media/python/myfiles/data/server/nginx --without-http_gzip_module
# 編譯
make
# 安裝
sudo make install
nginx簡單操作
# 檢查
.../data/server/nginx/sbin/nginx -t
# nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
# 先看報錯
ldd /data/server/nginx/sbin/nginx
# 顯示 libpcre.so.1 => not found
# 查看報錯文件
find / -name "libpcre.so.1"
# /home/python/anaconda3/pkgs/pcre-8.42-h439df22_0/lib/libpcre.so.1
# /home/python/anaconda3/lib/libpcre.so.1
# 找到文件,我沒有問題 是nginx默認找庫文件的路徑有問題
# 建立軟連鏈接--兩邊都使用絕對路徑
sudo ln -s /home/python/anaconda3/lib/libpcre.so.1 /lib/x86_64-linux-gnu/
# 再次檢查
sudo nginx/sbin/nginx -t
# /nginx/conf/nginx.conf syntax is ok
# /nginx/conf/nginx.conf test is successful
# 只有root才有權限訪問1024以下端口,故修改端口為7070
開啟
/data/server/nginx/sbin/nginx
關閉
/data/server/nginx/sbin/nginx -s stop
重載
/data/server/nginx/sbin/nginx -s reload
# netstat -anp | grep service_name # 查看某個服務的端口,不靈!!!
netstat -tnulp # 查看所有進程
# 可進行端口與pid的互相查詢
netstat -tnulp|grep pid或端口號 # 查找進程或端口的占用情況
# 殺死8000端口對應的進程
lsof -Pti :8000 # 查看端口對應的pid lsof-ti :8000 效果相同
kill $(lsof -Pti :8000)
lsof -i :端口號 # 查看端口對應的進程pid等信息
ps -ef|grep PID # 查看進程對應的詳細信息
使用 python manage.py runserver 啟動django項目時,直接使用ps aux|grep django是無法找到該進程的,可以根據端口號8000使用 lsof -i :8000或者 netstat -tnulp|grep 8000進行查找得到Pid,再使用ps -ef|grep PID 查看進程對應的詳細信息。
或者使用 ps aux|grep runserver查找到該服務對應的信息(不包含端口號)
記住兩個命令就夠了:
ps aux|grep xx 可查詢服務和進程
netstat -tnulp|grep xx 可查詢端口和進程
sudo passwd root # 設置root用戶密碼
su # 切換到管理員賬號
su '用戶名' # 切換到指定用戶
exit # 退出root用戶,回到前一用戶
6. 手工代碼發布
mkdir /data/{server,logs,backup,softs,virtual,scripts,codes} -p
# 虛擬環境搭建的兩種方式
# 方式1--這種默認安裝的是python2.x版本的,不推薦。
sudo pip3 install virtualenvs
sudo apt-get install virtualenvs
sudo apt-get install virtualenvswrapper
# 創建虛擬環境
mkvirtualenv -p python3 環境名稱 # 不指定python版本,則默認是2.x版本
workon 環境名稱 # 進入虛擬環境
pip install flask==0.10.1 # 指定版本安裝flask
# 方式2
apt-get install python-virtualenv -y
# /media/python/myfiles/.virtualenvs
virtualenv -p /home/python/anaconda3/bin/python3.7 kun
source kun/bin/activate
# 安裝django包
cd /media/python/myfiles/data/softs/Django-1.10.7
python setup.py install
# 創建django項目
cd .../data/server
django-admin startproject midou
# 創建應用
cd .../data/server/miduo
django-admin startapp user
# python manage.py startapp user
# 注冊應用
# vim midou/settings.py
33 INSTALLED_APPS = [
34 'django.contrib.admin',
35 'django.contrib.auth',
36 'django.contrib.contenttypes',
37 'django.contrib.sessions',
38 'django.contrib.messages',
39 'django.contrib.staticfiles',
40 'user',
41 ]
# view和url配置
vim user/views.py
1 from django.shortcuts import render
2 from django.http import HttpResponse
3
4 # Create your views here.
5
6 def hello(request):
7 return HttpResponse("midou V1.0")
vim midou/urls.py
16 from django.conf.urls import url
17 from django.contrib import admin
18
19 from user.views import *
20
21 urlpatterns = [
22 url(r'^admin/', admin.site.urls),
23 url(r'^hello/$', hello),
# 啟動django
python manage.py runserver
python manage.py runserver >> /dev/null 2>&1 &
訪問 http://127.0.0.1:8000/hello/
輸出 midou V1.0
# 安裝pcre包
# 解壓壓縮包
cd .../data/softs
tar zxf pcre-8.39.tar.gz
cd pcre-8.39
# 配置 -- 根據默認的配置項或者更改配置項,生成編譯配置文件(Makefile)
./configure
# 編譯 -- 根據 Makefile 內容,編譯生成指定的軟件所需要的所有文件
make
# 安裝 -- 將編譯生成的所有文件,轉移到指定安裝的目錄下面 --prefix
sudo make install
# 安裝ngix包
# 解壓壓縮包
cd .../data/soft/
tar zxf nginx-1.10.2.tar.gz
# 配置
cd nginx-1.10.2/
./configure --prefix=/media/python/myfiles/data/server/nginx --without-http_gzip_module
# 編譯
make
# 安裝
sudo make install
nginx簡單操作
# 檢查
.../data/server/nginx/sbin/nginx -t
# nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
# 先看報錯
ldd /data/server/nginx/sbin/nginx
# 顯示 libpcre.so.1 => not found
# 查看報錯文件
find / -name "libpcre.so.1"
# /home/python/anaconda3/pkgs/pcre-8.42-h439df22_0/lib/libpcre.so.1
# /home/python/anaconda3/lib/libpcre.so.1
# 找到文件,我沒有問題 是nginx默認找庫文件的路徑有問題
# 建立軟連鏈接--兩邊都使用絕對路徑
sudo ln -s /home/python/anaconda3/lib/libpcre.so.1 /lib/x86_64-linux-gnu/
# 再次檢查
sudo nginx/sbin/nginx -t
# /nginx/conf/nginx.conf syntax is ok
# /nginx/conf/nginx.conf test is successful
# 只有root才有權限訪問1024以下端口,故修改端口為7070
開啟
/data/server/nginx/sbin/nginx
關閉
/data/server/nginx/sbin/nginx -s stop
重載
/data/server/nginx/sbin/nginx -s reload
# netstat -anp | grep service_name # 查看某個服務的端口,不靈!!!
netstat -tnulp # 查看所有進程
# 可進行端口與pid的互相查詢
netstat -tnulp|grep pid或端口號 # 查找進程或端口的占用情況
# 殺死8000端口對應的進程
lsof -Pti :8000 # 查看端口對應的pid lsof-ti :8000 效果相同
kill $(lsof -Pti :8000)
lsof -i :端口號 # 查看端口對應的進程pid等信息
ps -ef|grep PID # 查看進程對應的詳細信息
使用 python manage.py runserver 啟動django項目時,直接使用ps aux|grep django是無法找到該進程的,可以根據端口號8000使用 lsof -i :8000或者 netstat -tnulp|grep 8000進行查找得到Pid,再使用ps -ef|grep PID 查看進程對應的詳細信息。
或者使用 ps aux|grep runserver查找到該服務對應的信息(不包含端口號)
記住兩個命令就夠了:
ps aux|grep xx 可查詢服務和進程
netstat -tnulp|grep xx 可查詢端口和進程
sudo passwd root # 設置root用戶密碼
su # 切換到管理員賬號
su '用戶名' # 切換到指定用戶
exit # 退出root用戶,回到前一用戶
6. 手工代碼發布
#!/bin/bash
# 功能:打包代碼
# 腳本名:tar_code.sh
# 作者:itcast
# 版本:V 0.3
# 聯系方式: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_tard
7. 腳本代碼發布
#!/bin/bash
# 功能:打包代碼
# 腳本名:deploy.sh
# 作者:kun
# 版本:V 0.6
# 定義本地 變量
ROOT='/media/python/myfiles/data'
LOG_FILE="${ROOT}/logs/deploy.log"
PID_FILE="${ROOT}/tmp/deploy.pid"
# 增加日志功能函數
write_log(){
DATE=$(date +%F)
TIME=$(date +%T)
buzhou="$1"
echo "${DATE} ${TIME} $0 : ${buzhou} " >> "${LOG_FILE}"
}
# 增加鎖文件
add_lock(){
echo "增加鎖文件"
touch "${PID_FILE}"
write_log "增加鎖文件"
}
# 刪除鎖文件
del_lock(){
echo "刪除鎖文件"
rm -f "${PID_FILE}"
write_log "刪除鎖文件"
}
# 獲取代碼
get_code(){
echo "獲取代碼"
write_log "獲取代碼"
}
# 打包代碼
tar_code(){
echo "打包代碼"
# ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh"
"/bin/bash ${ROOT}/scripts/tar_code.sh"
write_log "打包代碼"
}
# 傳輸代碼
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 ./
write_log "傳輸代碼"
}
# 關閉應用
stop_serv(){
echo "關閉應用"
write_log "關閉應用"
echo "關閉nginx應用"
${ROOT}/server/nginx/sbin/nginx -s stop
write_log "關閉nginx應用"
echo "關閉django應用"
kill $(lsof -Pti :8000)
write_log "關閉django應用"
}
# 解壓代碼
untar_code(){
echo "解壓代碼"
cd ${ROOT}/codes/
tar zxf django.tar.gz
write_log "解壓代碼"
}
# 放置代碼
fangzhi_code(){
echo "放置代碼"
write_log "放置代碼"
echo "備份老文件"
mv ${ROOT}/server/midou/user/views.py ${ROOT}/backup/views.py-$(date +%Y%m%d%H%M%S)
write_log "備份老文件"
echo "放置新文件"
cd ${ROOT}/codes
mv django/views.py ${ROOT}/server/midou/user/
write_log "放置新文件"
}
# 開啟應用
start_serv(){
echo "開啟應用"
write_log "開啟應用"
echo "開啟django應用"
source ${ROOT}/../.virtualenvs/kun/bin/activate
cd ${ROOT}/server/midou/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
write_log "開啟django應用"
echo "開啟nginx應用"
${ROOT}/server/nginx/sbin/nginx
write_log "開啟nginx應用"
}
# 檢查
check(){
echo "檢查應用"
netstat -tnulp | grep ':80'
write_log "檢查應用"
}
# 部署函數
pro_deploy(){
add_lock
get_code
tar_code
scp_code
stop_serv
untar_code
fangzhi_code
start_serv
check
del_lock
}
# 報錯信息
err_msg(){
echo "該腳本 $0 正在運行,請稍候..."
}
# 幫助信息
usage(){
echo "腳本 $0 的使用方式是: $0 [ deploy ]"
}
# 主函數
main(){
case "$1" in
deploy)
if [ -f "${PID_FILE}" ]
then
err_msg
else
pro_deploy
fi
;;
*)
usage
;;
esac
}
# 調用主函數
if [ "$#" -ne 1 ]
then
usage
else
main $1
fi
擴展
date +%Y%m%d //顯示前天年月日
date +%Y%m%d --date="+1 day" //顯示前一天的日期
date +%Y%m%d --date="-1 day" //顯示后一天的日期
date +%s //從 1970 年 1 月 1 日 00:00:00 UTC 到目前為止的秒數(時間戳)
vDay=`echo ${vDay}|awk '{print substr($0,1,4)"-"substr($0,5,2)"-"substr($0,7,2)}'`
