3.2 shell 基础知识
3.2.1 shell 是什么
shell 贝壳
shell就是一个命令解释器[重点]

3.2.2 shell 分类
基本上shell分两大类:
图形界面shell和命令行shell

图形界面shell
gnome,kde

命令行shell
windows:cmd.exe
linux:bash

shell的历史:
sh ksh csh bash[重点]
1970左右
程序设计语言

常见的linux发行版本:
ubuntu
centos
6.5-6.8   7.0
redhat
debian
生产上重点:
稳定压倒一切

shell命令执行特点:
逐行输入命令、逐行进行确认

3.2.3 shell 脚本
shell脚本是什么
就是一堆可执行命令的组合[重点]

shell脚本开发规范
1、命名:
要有意义,后缀.sh
2、首行
是而且必须是命令解释器
3、注释
简单描述脚本信息
脚本描述、脚本名称、脚本版本号、作者、联系方式
4、执行
bash 脚本名称
5、脚本内容
从上到下,依次执行。
6、其他
成对的符号,成对写,避免丢失
() {} [] '' ""
流程格式:
先写完,然后填空
缩进
仅仅是表示美观

脚本执行方式
方式一:
bash 脚本名称
bash test.sh
/bin/bash /data/scripts/python10/test.sh

场景:
工作中常用[*****]

方式二:
文件的路径
示例:
/data/scripts/python10/test.sh
./test.sh

重点:
文件一定要有执行权限

场景:
工作中常用

方式三:
source 或者 .
加载

场景:
保证环境一致性

案例:
某个脚本在你自己的笔记本可以执行成功,但是在其他人机器上执行失败,
原因就是:环境不一致

超前知识点:
命令变量的定义:
dir=`pwd`
查看变量的方式
echo $dir

注释
单行注释: #
多行注释:
:<<!。。。!

示例:
#!/bin/bash
:<<!
脚本描述:测试命令行输入
作者:python 13期
版本:v1.0
联系方式:中南海
!
dir=`pwd`
echo $dir

3.2.4 shell & python

执行方式
shell脚本直接调用系统命令执行

为什么运维shell使用比例比python高
执行python --- 导入模块 -- 模块调用系统命令 --- 执行

调用系统命令情况下,
shell效率比python高

对比

shell 杀猪刀 干净利索 快
python 导弹 需要模块帮助、实现功能多、 慢

3.3 shell 变量
3.3.1 shell变量是什么
变量:
存储动态值的一个抽象概念

变量包括两部分:
变量名 不变的
变量值 变化的

变量之歌:
星星还是那个星星

变量名 星星
变量值 时间

散文 形散而神不散
变量名 神
变量值 形式

我的角色
变量名 我
变量值 角色

3.3.2 常见变量

本地变量
在本地有效

全局变量
在当前系统下,所有环境都有效

内置变量
bash中内置了很多变量,我们可以直接拿过来使用

3.3.3 本地变量
普通变量:
方式一:
变量名=变量值
重点:
变量值必须是一个整体,中间没有特殊字符

方式二:
变量名='变量值'
重点:
我看到的内容,我就输出什么内容

方式三:
变量名="变量值"
重点:
如果变量值范围内,有可以解析的变量A,那么首先解析变量A,将A的结果和其他内容组合成一个整体,重新赋值给变量B

示例:
# echo $itcast

# itcast=nihao
# echo $itcast
nihao
# itcast1=nihao 666
666: command not found
# itcast1="nihao 666"
# echo $itcast1
nihao 666
# itcast2='nihao 777'
# echo $itcast2
nihao 777
# echo $itcast
nihao
# itcast3='nihao 666-$itcast'
# echo $itcast3
nihao 666-$itcast
# itcast4="nihao 666-$itcast"
# echo $itcast4
nihao 666-nihao

命令变量
变量名=`命令`
注:是反引号,而不是单引号。
变量名=$(命令)

执行流程:
1、执行命令
2、将命令执行后的结果,赋值给新的变量名A

变量的查看:

方式一:
$变量名
场景:
私下里,在命令行/脚本中使用
图省事

方式二:
"$变量名"

方式三:
${变量名}
场景:
echo " dsa  dsafsa  dsafsa ${变量名} f "

方式四:
"${变量名}"
场景:
标准使用方式,

3.3.4 全局变量
定义方式:
方式一:
1、首先定义一个本地变量
2、使用export声明这个本地变量为全局变量
示例:
root@admina-virtual-machine:/data/scripts/python10# itcast5=qiang666
root@admina-virtual-machine:/data/scripts/python10# export itcast5=qiang666
root@admina-virtual-machine:/data/scripts/python10# env | grep itcast
itcast=nihao
itcast5=qiang666
itcast1=nihao 666

方式二:
我定义本地变量的同时,使用export声明本地变量为全局变量

示例:
root@admina-virtual-machine:/data/scripts/python10# export itcast5=qiang666
root@admina-virtual-machine:/data/scripts/python10# env | grep itcast
itcast=nihao
itcast5=qiang666
itcast1=nihao 666

全局变量查看方式
查看方式:
env
set
declare

删除变量
格式:
unset 变量名

示例:
root@admina-virtual-machine:/data/scripts/python10# env | grep itcast
itcast=nihao
itcast5=qiang666
itcast1=nihao 666
root@admina-virtual-machine:/data/scripts/python10# unset itcast
root@admina-virtual-machine:/data/scripts/python10# unset itcast1
root@admina-virtual-machine:/data/scripts/python10# unset itcast2
root@admina-virtual-machine:/data/scripts/python10# unset itcast3
root@admina-virtual-machine:/data/scripts/python10# unset itcast4
root@admina-virtual-machine:/data/scripts/python10# unset itcast5
root@admina-virtual-machine:/data/scripts/python10# env | grep itcast
root@admina-virtual-machine:/data/scripts/python10# echo $itcast2

root@admina-virtual-machine:/data/scripts/python10# echo $itcast3

root@admina-virtual-machine:/data/scripts/python10# echo $itcast4

3.3.5 内置变量
跟脚本文件有关系的变量
$0 获取脚本的名称
示例:
root@admina-virtual-machine:/data/scripts/python10# bash file1.sh 
我脚本的名称是: file.sh
我脚本的名称是:file1.sh
root@admina-virtual-machine:/data/scripts/python10# cat file1.sh 
#!/bin/bash
# 获取脚本的名称
echo "我脚本的名称是: file.sh"
echo "我脚本的名称是:$0"
场景:
获取当前脚本的使用方式
root@admina-virtual-machine:/data/scripts/python10# bash file1.sh 
file1.sh 脚本的使用方法:file1.sh  [ arg1 | arg2 ]
root@admina-virtual-machine:/data/scripts/python10# cat file1.sh 
#!/bin/bash
# 获取脚本的名称
echo "$0 脚本的使用方法:$0  [ arg1 | arg2 ]"

$# 获取当前脚本传入参数的数量
示例:
root@admina-virtual-machine:/data/scripts/python10# cat num.sh 
#!/bin/bash
# 获取当前脚本传入的参数数量
echo "当前脚本传入的参数数量是: $#"
root@admina-virtual-machine:/data/scripts/python10# bash num.sh 
当前脚本传入的参数数量是: 0
root@admina-virtual-machine:/data/scripts/python10# bash num.sh a
当前脚本传入的参数数量是: 1
root@admina-virtual-machine:/data/scripts/python10# bash num.sh a dsanfdsn dsa f ds f ds af dsa f dsa f dsa f ds fds  fds af ds  fds  fds  fds f sa f ds af ds af dsa  sd f dsa  fd
当前脚本传入的参数数量是: 34

场景:
判断我输入的参数数量是否是我要求的个数

需求:
我的脚本只允许传入两个参数,如果输入参数不对,那么输出脚本的执行帮助

root@admina-virtual-machine:/data/scripts/python10# cat num1.sh 
#!/bin/bash
# 判断传入参数数量
[ "$#" -eq 2 ] && echo "$0 开始执行..."
[ "$#" -eq 2 ] || echo "$0 帮助: $0 [ arg1 ]"
root@admina-virtual-machine:/data/scripts/python10# bash num1.sh 
num1.sh 帮助: num1.sh [ arg1 ]
root@admina-virtual-machine:/data/scripts/python10# bash num1.sh 2
num1.sh 帮助: num1.sh [ arg1 ]
root@admina-virtual-machine:/data/scripts/python10# bash num1.sh 2 2
num1.sh 开始执行...

$n 获取当前脚本传入的第n个位置的参数
示例:
root@admina-virtual-machine:/data/scripts/python10# cat weizhi.sh 
#!/bin/bash
# 获取指定位置的参数
echo "第一个位置的参数是: $1"
echo "第二个位置的参数是: $2"
echo "第三个位置的参数是: $3"
echo "第四个位置的参数是: $4"
root@admina-virtual-machine:/data/scripts/python10# bash weizhi.sh 1
第一个位置的参数是: 1
第二个位置的参数是: 
第三个位置的参数是: 
第四个位置的参数是: 
root@admina-virtual-machine:/data/scripts/python10# bash weizhi.sh 1 2 3 4
第一个位置的参数是: 1
第二个位置的参数是: 2
第三个位置的参数是: 3
第四个位置的参数是: 4

场景:
1、脚本同时传入多个参数
2、脚本中有不同的函数专门调用不同位置的传参

执行脚本的方式:
bash 脚本名  arg1  arg2

脚本的内容:
函数1 $1
函数2 $2

$? 获取文件执行或者命令执行的返回状态值
示例:
root@admina-virtual-machine:/data/scripts/python10# bash nihao
bash: nihao: No such file or directory
root@admina-virtual-machine:/data/scripts/python10# echo $?
127
root@admina-virtual-machine:/data/scripts/python10# ls
file1.sh  num.sh  test.sh  weizhi.sh
root@admina-virtual-machine:/data/scripts/python10# echo $?
0
root@admina-virtual-machine:/data/scripts/python10# llllllll
llllllll: command not found
root@admina-virtual-machine:/data/scripts/python10# echo $?
127

场景:
root@admina-virtual-machine:/data/scripts/python10# bash zhuangtai.sh 
执行返回状态值是 0
/data/scripts/python10
执行返回状态值是 0
当前dir位置是 /data/scripts/python10
执行返回状态值是 0
root@admina-virtual-machine:/data/scripts/python10# cat zhuangtai.sh 
#!/bin/bash
# 文件执行返回状态值演示
cd /data/scripts/python10
echo "执行返回状态值是 $?"
pwd
echo "执行返回状态值是 $?"
./test.sh
echo "执行返回状态值是 $?"

获取随机字符串
场景
创建一个用户,密码是随机生成

生成随机数
$RANDOM 生成随机的5位数以内的数字

示例:
root@admina-virtual-machine:/data/scripts/python10# echo $RANDOM
18061
root@admina-virtual-machine:/data/scripts/python10# echo $RANDOM | md5sum
27e8fda6333d9716503ff007cbd4cdb7  -
root@admina-virtual-machine:/data/scripts/python10# echo $RANDOM | md5sum | awk '{print $1}'
3a8d2e3493d99151f43b68df8ab09fdc
root@admina-virtual-machine:/data/scripts/python10# str=$(echo $RANDOM | md5sum | awk '{print $1}')
root@admina-virtual-machine:/data/scripts/python10# echo $str
e111ef894a8fd92979c4331386901381

字符串相关的内置变量
截取
${变量名:起始位置:截取长度}

示例:从头截取8个字符
root@admina-virtual-machine:/data/scripts/python10# echo $str
e111ef894a8fd92979c4331386901381
root@admina-virtual-machine:/data/scripts/python10# echo ${str:0:8}
e111ef89

示例:从第5个位置开始,截取8个字符
root@admina-virtual-machine:/data/scripts/python10# echo ${str:4:8}
ef894a8f

示例:从末尾截取8个字符
root@admina-virtual-machine:/data/scripts/python10# echo ${str: -8}
86901381
root@admina-virtual-machine:/data/scripts/python10# echo ${str:0-8}
86901381
注意:
${str: -8}
${str:0-8}

只有一个冒号,空格或者0

默认值
场景一:
变量a如果有内容,那么就输出a的变量值
变量a如果没有内容,那么就输出默认的内容

格式:
${变量名:-默认值}

套餐示例:
如果我输入的参数为空,那么输出内容是 "您选择的套餐是: 套餐 1"
如果我输入的参数为n,那么输出内容是 "您选择的套餐是: 套餐 n"

root@admina-virtual-machine:/data/scripts/python10# cat select.sh 
#!/bin/bash
# 套餐选择演示
a="$1"

echo "您选择的套餐是: 套餐 ${a:-1}"
root@admina-virtual-machine:/data/scripts/python10# bash select.sh 
您选择的套餐是: 套餐 1
root@admina-virtual-machine:/data/scripts/python10# bash select.sh 2
您选择的套餐是: 套餐 2
root@admina-virtual-machine:/data/scripts/python10# bash select.sh 6
您选择的套餐是: 套餐 6

场景二:
无论变量a是否有内容,都输出默认值
格式:
${变量名+默认值}
场景示例:
不管我说国家法定结婚年龄是 多少岁,都输出 国家法定结婚年龄(男性)是 22 岁

root@admina-virtual-machine:/data/scripts/python10# cat age.sh 
#!/bin/bash
# 默认值演示示例二
a="$1"
echo "国家法定结婚年龄(男性)是 ${a+22} 岁"
root@admina-virtual-machine:/data/scripts/python10# bash age.sh 3
国家法定结婚年龄(男性)是 22 岁
root@admina-virtual-machine:/data/scripts/python10# bash age.sh 300
国家法定结婚年龄(男性)是 22 岁

3.4 shell 表达式
3.4.1 shell验证操作
方式一:
[ 表达式 ]

0 表示表达式成立
1 表示表达式不成立

方式二:
test 表达式

示例:
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 1 ]
root@admina-virtual-machine:/data/scripts/python10# echo $?
0
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 2 ]
root@admina-virtual-machine:/data/scripts/python10# echo $?
1
root@admina-virtual-machine:/data/scripts/python10# test 1 = 1
root@admina-virtual-machine:/data/scripts/python10# echo $?
0
root@admina-virtual-machine:/data/scripts/python10# test 1 = 2
root@admina-virtual-machine:/data/scripts/python10# echo $?
1

3.4.2 shell表达式
逻辑
&&
命令1  &&  命令2
如果命令1执行成功,那么我才执行命令2 -- 夫唱妇随
如果命令1执行失败,那么命令2也不执行
示例:
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 1 ] && echo "条件成立"
条件成立
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 2 ] && echo "条件成立"
root@admina-virtual-machine:/data/scripts/python10#

||
命令1 || 命令2
如果命令1执行成功,那么命令2不执行 -- 对着干
如果命令1执行失败,那么命令2执行
示例:
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 2 ] || echo "条件不成立"
条件不成立
root@admina-virtual-machine:/data/scripts/python10# [ 1 = 1 ] || echo "条件不成立"
root@admina-virtual-machine:/data/scripts/python10#

文件

-f 判断输入内容是否是一个文件
示例:
root@admina-virtual-machine:/data/scripts/python10# [ -f weizhi.sh ] && echo "是一个文件"
是一个文件
root@admina-virtual-machine:/data/scripts/python10# [ -f weizhi.sddh ] || echo "不是一个文件"
不是一个文件

-d 判断输入内容是否是一个目录
示例:
root@admina-virtual-machine:/data/scripts/python10# [ -d weizhi.sddh ] || echo "不是一个目录"
不是一个目录
root@admina-virtual-machine:/data/scripts/python10# mkdir nihao
root@admina-virtual-machine:/data/scripts/python10# ls
age.sh  file1.sh  nihao  num1.sh  num.sh  select.sh  test.sh  weizhi.sh  zhuangtai.sh
root@admina-virtual-machine:/data/scripts/python10# [ -d nihao ] && echo "是一个目录"
是一个目录

-x 判断输入内容是否可执行
示例:
root@admina-virtual-machine:/data/scripts/python10# [ -x age.sh ] || echo "文件没有执行权限"
文件没有执行权限
root@admina-virtual-machine:/data/scripts/python10# [ -x test.sh ] && echo "文件有执行权限"
文件有执行权限
root@admina-virtual-machine:/data/scripts/python10# [ -x test.sh ] && ./test.sh 
当前dir位置是 /data/scripts/python10

数字
-gt 大于
-lt 小于
-eq 等于
-ne 不等于

场景:
root@admina-virtual-machine:/data/scripts/python10# cat num2.sh 
#!/bin/bash
# 数字表达式 -ne使用场景
[ "$#" -ne 2 ] && echo " $0 脚本使用帮助信息: $0 [ arg1 arg2 ]"
[ "$#" -eq 2 ] && echo "$0 脚本正在执行......"
root@admina-virtual-machine:/data/scripts/python10# bash num2.sh 
num2.sh 脚本使用帮助信息: num2.sh [ arg1 arg2 ]
root@admina-virtual-machine:/data/scripts/python10# bash num2.sh 2
num2.sh 脚本使用帮助信息: num2.sh [ arg1 arg2 ]
root@admina-virtual-machine:/data/scripts/python10# bash num2.sh 2 2
num2.sh 脚本正在执行......
root@admina-virtual-machine:/data/scripts/python10# bash num2.sh 2 2 3
num2.sh 脚本使用帮助信息: num2.sh [ arg1 arg2 ]

字符串
== 两侧的内容是一致的
!= 两侧的内容是不一致的

使用场景:
root@admina-virtual-machine:/data/scripts/python10# cat str.sh 
#!/bin/bash
# 字符串表达式的演示
a="$1"
b="$2"

[ "${a}" == "${b}" ] && echo "您输入的两个参数内容是一致的"
[ "${a}" != "${b}" ] && echo "您输入的两个参数内容是不一致的"

root@admina-virtual-machine:/data/scripts/python10# bash str.sh abc abc
您输入的两个参数内容是一致的
root@admina-virtual-machine:/data/scripts/python10# bash str.sh abc abcd
您输入的两个参数内容是不一致的

3.5 shell 流程控制

3.5.1 简单流程控制

选择
python if语句格式:

python中的流程控制:

if语句:
单if语句:
if 条件:
执行语句

双if语句:
if 条件:
执行语句
else:
执行语句2

多if语句:
if 条件1:
执行语句1
elif 条件2:
执行语句2
else:
执行语句2

shell中的if
单if语句:
格式:
if 条件
then
执行语句
fi
重点:
首行关键字是if
末行关键字是fi
场景:
单一条件,只有一个输出

示例:
如果我输入内容是 nan
root@admina-virtual-machine:/data/scripts/python10# bash danif.sh nan
您的性别是 男
root@admina-virtual-machine:/data/scripts/python10# cat danif.sh 
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
fi

双if语句:
格式:
if 条件
then
执行语句
else
执行语句2
fi

场景:
一个条件,两种结果

示例:
root@admina-virtual-machine:/data/scripts/python10# cat shuangif.sh 
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
else
   echo "您的性别是 女"
fi
root@admina-virtual-machine:/data/scripts/python10# bash shuangif.sh nan
您的性别是 男
root@admina-virtual-machine:/data/scripts/python10# bash shuangif.sh nv
您的性别是 女
root@admina-virtual-machine:/data/scripts/python10# bash shuangif.sh nvdsaf
您的性别是 女

多if语句:
格式:
if 条件1
then
执行语句1
elif 条件2
then
执行语句2
else
执行语句3
fi

场景:
n个条件,n+1个结果

示例:
root@admina-virtual-machine:/data/scripts/python10# cat duoif.sh 
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
elif [ "$1" == "nv" ]
then
   echo "您的性别是 女"
else
   echo "您的性别,我不知道"
fi
root@admina-virtual-machine:/data/scripts/python10# bash duoif.sh 
您的性别,我不知道
root@admina-virtual-machine:/data/scripts/python10# bash duoif.sh nan
您的性别是 男
root@admina-virtual-machine:/data/scripts/python10# bash duoif.sh nv
您的性别是 女
root@admina-virtual-machine:/data/scripts/python10# bash duoif.sh nvdsaf
您的性别,我不知道

场景:
服务的启动
需求:
start 启动
stop 关闭
restart 重启
* 脚本使用方式

root@admina-virtual-machine:/data/scripts/python10# cat if.sh 
#!/bin/bash
# 多if语句的使用场景
if [ "$1" == "start" ]
then
   echo "启动 $0 脚本"
elif [ "$1" == "stop" ]
then
   echo "关闭 $0 脚本"
elif [ "$1" == "restart" ]
then
   echo "重启 $0 脚本"
else
   echo "$0 脚本的使用方式: $0 [ start | stop | restart ]"
fi
root@admina-virtual-machine:/data/scripts/python10# bash if.sh 
if.sh 脚本的使用方式: if.sh [ start | stop | restart ]
root@admina-virtual-machine:/data/scripts/python10# bash if.sh start
启动 if.sh 脚本
root@admina-virtual-machine:/data/scripts/python10# bash if.sh stop
关闭 if.sh 脚本
root@admina-virtual-machine:/data/scripts/python10# bash if.sh restart
重启 if.sh 脚本

case语句
格式:
case 值 in
值1)
执行语句
;;
值1)
执行语句
;;
值1)
执行语句
;;
值1)
执行语句
;;
esac

场景:服务启动
root@admina-virtual-machine:/data/scripts/python10# cat case.sh 
#!/bin/bash
# case语句使用场景
case "$1" in
"start")
echo "启动 $0 脚本"
;;
"stop")
echo "关闭 $0 脚本"
;;
"restart")
echo "重启 $0 脚本"
;;
*)
echo "$0 脚本的使用方式: $0 [ start | stop | restart ]"
;;
esac
root@admina-virtual-machine:/data/scripts/python10# bash case.sh 
case.sh 脚本的使用方式: case.sh [ start | stop | restart ]
root@admina-virtual-machine:/data/scripts/python10# bash case.sh start
启动 case.sh 脚本
root@admina-virtual-machine:/data/scripts/python10# bash case.sh stop
关闭 case.sh 脚本
root@admina-virtual-machine:/data/scripts/python10# bash case.sh restart
重启 case.sh 脚本

循环
python格式:
for语句:
for 条件:
执行语句
while语句:
while 条件:
执行语句

until语句:
until 条件:
执行语句

shell的格式:
for 语句:
格式;
for 条件
do
执行语句
done

场景:
遍历列表

示例:遍历文件
root@admina-virtual-machine:/data/scripts/python10# ls
age.sh   danif.sh  file1.sh  nihao    num2.sh  select.sh    str.sh   weizhi.sh
case.sh  duoif.sh  if.sh     num1.sh  num.sh   shuangif.sh  test.sh  zhuangtai.sh

root@admina-virtual-machine:/data/scripts/python10# cat for.sh 
#!/bin/bash
# for语句的使用示例
file=`ls /data/scripts/python10`
for i in "${file}"
do
  echo "${i}"
done
root@admina-virtual-machine:/data/scripts/python10# bash for.sh 
age.sh
case.sh
danif.sh
duoif.sh
file1.sh
for.sh
if.sh
...

示例2:遍历数字
root@admina-virtual-machine:/data/scripts/python10# cat for1.sh 
#!/bin/bash
# for 语句示例2
num=$(seq 10)
for i in "${num}"
do
  echo "${i}"
done
root@admina-virtual-machine:/data/scripts/python10# bash for1.sh 
1
2
3
4
5
6
7
8
9
10

shell中的计算方法:
格式;
let 变量名a=变量名a+1
a=$((变量名a+1))

示例:
root@admina-virtual-machine:/data/scripts/python10# echo $a

root@admina-virtual-machine:/data/scripts/python10# a=1
root@admina-virtual-machine:/data/scripts/python10# let a=a+1
root@admina-virtual-machine:/data/scripts/python10# echo $a
2
root@admina-virtual-machine:/data/scripts/python10# a=$((a+1))
root@admina-virtual-machine:/data/scripts/python10# echo $a
3

while 语句:
格式;
while 条件
do
执行语句
done

场景:
如果条件满足,那么我一直循环下去

示例:
root@admina-virtual-machine:/data/scripts/python10# cat while.sh 
#!/bin/bash
# while的示例
a=1
while [ "${a}" -lt 5 ] 
do
   echo "${a}"
   a=$((a+1))
done
root@admina-virtual-machine:/data/scripts/python10# bash while.sh 
1
2
3
4

until 语句:
格式;
until 条件
do
执行语句
done

场景:
如果条件不满足,那么我一直循环下去

示例:
root@admina-virtual-machine:/data/scripts/python10# cat until.sh 
#!/bin/bash
# until的示例
a=1
until [ "${a}" -gt 4 ] 
do
   echo "${a}"
   a=$((a+1))
done
root@admina-virtual-machine:/data/scripts/python10# bash until.sh 
1
2
3
4

3.5.2 复杂流程控制
python的函数
定义函数:
def 函数名():
函数体
调用
函数名()

传参数
def 函数名(参数):
函数体

调用传参数
函数名(参数)

shell函数格式:
定义函数:
函数名(){
函数体
}

调用函数:
函数名

传参数
函数名 参数

函数体调用参数:
函数名(){
函数体 $n
}
注意:
类似于shell内置变量中的位置参数

定义和调用函数示例:
root@admina-virtual-machine:/data/scripts/python10# bash fun2.sh 
wo de mingzi shi  111
root@admina-virtual-machine:/data/scripts/python10# cat fun2.sh 
#!/bin/bash
# 函数使用场景一:执行频繁的命令
dayin(){
  echo "wo de mingzi shi  111"
}
dayin

函数传参和函数体内调用参数的示例
root@admina-virtual-machine:/data/scripts/python10# bash fun4.sh 
wo de mingzi shi 111
root@admina-virtual-machine:/data/scripts/python10# cat fun4.sh 
#!/bin/bash
# 函数的使用场景二
dayin(){
  echo "wo de mingzi shi $1"
}
dayin 111

函数使用场景:
执行频繁的命令
或者
执行命令格式相近的命令

场景一:执行频繁的命令
root@admina-virtual-machine:/data/scripts/python10# bash fun1.sh 
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
root@admina-virtual-machine:/data/scripts/python10# cat fun1.sh 
#!/bin/bash
# 输出一大堆执行频繁的命令
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
echo "wo de mingzi shi  111"
函数演变一下
root@admina-virtual-machine:/data/scripts/python10# cat fun2.sh 
#!/bin/bash
# 函数使用场景一:执行频繁的命令
dayin(){
  echo "wo de mingzi shi  111"
}
dayin
dayin
dayin
dayin
dayin
dayin
root@admina-virtual-machine:/data/scripts/python10# bash fun2.sh 
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111
wo de mingzi shi  111

场景二;执行命令格式相近的命令
root@admina-virtual-machine:/data/scripts/python10# cat fun3.sh 
#!/bin/bash
# 输出格式相近的命令
echo "wo de mingzi shi  1a11"
echo "wo de mingzi shi  11d1"
echo "wo de mingzi shi  111d"
echo "wo de mingzi shi  111s"
echo "wo de mingzi shi  111a"
echo "wo de mingzi shi  111s"
echo "wo de mingzi shi  111s"
echo "wo de mingzi shi  111d"
echo "wo de mingzi shi  111f"
echo "wo de mingzi shi  111e"
root@admina-virtual-machine:/data/scripts/python10# bash fun3.sh 
wo de mingzi shi  1a11
wo de mingzi shi  11d1
wo de mingzi shi  111d
wo de mingzi shi  111s
wo de mingzi shi  111a
wo de mingzi shi  111s
wo de mingzi shi  111s
wo de mingzi shi  111d
wo de mingzi shi  111f
wo de mingzi shi  111e

函数演变
root@admina-virtual-machine:/data/scripts/python10# cat fun4.sh 
#!/bin/bash
# 函数的使用场景二
dayin(){
  echo "wo de mingzi shi $1"
}
dayin 111
root@admina-virtual-machine:/data/scripts/python10# vim fun4.sh 
root@admina-virtual-machine:/data/scripts/python10# bash fun4.sh 
wo de mingzi shi 111
wo de mingzi shi 111s
wo de mingzi shi 111d
wo de mingzi shi 111g
wo de mingzi shi 111d
root@admina-virtual-machine:/data/scripts/python10# cat fun4.sh 
#!/bin/bash
# 函数的使用场景二
dayin(){
  echo "wo de mingzi shi $1"
}
dayin 111
dayin 111s
dayin 111d
dayin 111g
dayin 111d

函数传参多个,函数体内调用示例
root@admina-virtual-machine:/data/scripts/python10# bash fun4.sh 
wo de mingzi shi 111
wo de mingzi shi df
wo de mingzi shi dfs
root@admina-virtual-machine:/data/scripts/python10# cat fun4.sh 
#!/bin/bash
# 函数的使用场景二
dayin(){
  echo "wo de mingzi shi $1"
  echo "wo de mingzi shi $2"
  echo "wo de mingzi shi $3"
}
dayin 111 df dfs

1、项目周期
1.1 项目周期
需求:
开发
开发经理拆分项目
1、人员
2、技术水平

组员:
项目的子模块

项目交给测试之前,需要项目的联调后,联调的时候,需要开发团队都在一起

测试
部署
运营

1.2 项目开发环境
个人开发环境
个人笔记本
公司配的电脑

特点:
环境是自己配的,团队中不同的个人开发环境可以不一样
代码版本、软件版本、工具....

工作内容:
项目的子模块,子功能

工作人员:
自己

最终目的:
领导安排的内容,完成
项目的子模块开发完成

公司开发环境
公司内部的服务器,
特点:
服务器环境和线上的服务器环境完全一致

工作内容:
项目子模块间的功能联调

工作人员
开发团队所有人

最终目的:
项目开发完成
项目调试完成

测试环境:
公司内部的服务器,
特点:
服务器环境和线上的服务器环境完全一致

工作内容:
找茬

工作人员
测试团队

最终目的:
保证项目功能完备

预发布环境:
公司线上服务器组中的一台,
特点:
服务器环境和线上的服务器环境完全一致

工作内容:
1、支付类型的特殊功能
2、数据压力测试
3、其他安全措施

工作人员
运维团队

最终目的:
保证项目功能完备

线上环境
公司线上服务器组

工作内容:
代码部署

工作人员
运维团队

最终目的:
保证项目功能完备

2、代码发布
2.1 什么是部署
部署什么?
代码 经过测试,功能完善,没有问题的代码
部署到哪里?
服务器 所有人都能访问的到的一台服务器(有公网IP)
阿里云、亚马逊、腾讯云、华为云、....
部署的效果
web网页对外展示

2.2 部署方式
手工发布代码 步行

干扰因素多
不安全

脚本发布代码 坐车

干扰因素少
安全

2.3 部署流程
获取代码

代码仓库
集中式的
svn
分布式的
git

公司的代码仓库:
私有仓库 gitlab
内部服务器。或者公网服务器

仓库权限
只有项目的开发人员才有权限,项目之外的人没有权限

代码权限:
开发、管理、查看

提交的方式:
代码版本号

打包代码:
目的:
减少传输文件数量
减小传输文件大小
增强传输速率

常见打包方式:
windows:
zip、rar...
linux:
tar、zip...

传输代码
传输方式:
有网情况下
git
ftp
scp
共享挂载 cp
rsync

没有网情况下
物理方式 
U盘或者硬盘

传输工具演示:
格式:
scp  要传输的文件 要放置的位置

将本地文件推送到远程主机
scp python10.tar.gz root@192.168.56.12:/root/
远程连接的用户@远程主机:远程主机的位置
将远程主机的文件拉取到本地
scp root@192.168.56.12:/root/python10.tar.gz ./

主机间免秘钥认证
1、生成秘钥对
ssh-keygen -t rsa
-t 指定秘钥的类型  
rsa 秘钥类型

秘钥目录:/root/.ssh/
私钥 id_rsa 钥匙
公钥 id_rsa.pub 锁

2、编辑认证文件
root@admina-virtual-machine:~/.ssh# cat /root/.ssh/authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDdC36zf/x+K8BQx582r+uYx78NC6s24PljsnpL6mELJkcXEVvIQ49lWpeJJm58F9j73J3h342WeaW50HzkxvcZGOqdx/pOp6tphkqlIe3utnJlRYvhSmULGFMBC1C0dNWcU/igK28XYBe3Rwhzh43vb5cc2jh90Ef2iQTny2RzjT11B2pro02wGGdcPKRHQkVfHdCkPa1iFsL2YHuYDr8XPMCcfbLfNUUSugGq2VoqpmjdR+G1xXgoHnAucFUMwHVTeGXEDiqFd56fPeEHQ9cSeVAFiQeqKeiNLvjQ0LJCgIy4TEx1DTc//3ND9TQbCA6NZJt4zgNc19jqAdT/PVp root@admina-virtual-machine
注意:
认证文件内容和56.11机器的公钥文件内容一致
保证文件内容是一整行

3、编辑ssh配置文件
root@admina-virtual-machine:~/.ssh# cat /etc/ssh/sshd_config
...
AuthorizedKeysFile %h/.ssh/authorized_keys
注意:
直接取消该行的注释即可

4、配置文件生效
重启ssh服务
/etc/init.d/ssh restart

5、验证操作
ssh root@192.168.56.12

1和5是在56.11上操作
2-4是在56.12上操作

关闭应用
开启什么应用,就关闭什么应用

解压代码:
tar xf ...

放置代码
备份原文件
cp nihao nihao-`date +%Y%m%d%H%M%S`

放置新文件

注意:
两个文件的名称是一样的,只是内容不同
对整个应用项目来说,两个文件没有区别

时间戳效果:
年月日时分秒:date +%Y%m%d%H%M%S

年月日:date +%Y%m%d
时分秒:date +%H%M%S

时间戳生成示例:
root@admina-virtual-machine:~/.ssh# date +%D
09/28/17
root@admina-virtual-machine:~/.ssh# date +%F
2017-09-28
root@admina-virtual-machine:~/.ssh# date +%Y%m%d
20170928
root@admina-virtual-machine:~/.ssh# date +%T
03:06:30
root@admina-virtual-machine:~/.ssh# date +%H%M%S
030643
root@admina-virtual-machine:~/.ssh# date +%Y%m%d%H%M%S
20170928030742

开启应用
关闭什么应用就开启什么应用

检查
查看浏览器效果

ok

3、环境部署
3.1 准备工作
创建基本目录
root@admina-virtual-machine:/data# mkdir /data/{server,logs,backup,soft,virtual}
root@admina-virtual-machine:/data# ls /data/
backup  logs  scripts  server  soft  virtual
root@admina-virtual-machine:/data# mkdir /data/codes
查看
root@admina-virtual-machine:/data# tree -L 1 /data/ 
/data/
├── backup 备份
├── codes 代码
├── logs 日志
├── scripts 脚本
├── server 服务
├── soft 软件
└── virtual 虚拟环境
3.2 项目分析
需求:
部署一个环境,支持我们的django项目正常运行

分析:

2、python环境 --->  3、python虚拟环境
1、django环境部署
4、django软件安装
5、项目基本操作
6、应用基本操作
7、view和url配置
8、问题:只有本机能访问
9、方案代理---- 10、nginx
11、nginx实现代理
13、pcre软件安装
12、nginx软件安装
14、nginx基本操作
15、nginx代理的配置
16、目录结构
17、查看配置文件
18、找到对应的代理配置项
19、启动django
20、启动nginx
21、整个项目调试

3.2 python虚拟环境
3.2.1 软件安装
apt-get install python-virtualenv -y

3.2.2 虚拟环境基本操作
创建 
virtualenv -p /usr/bin/python2.7 venv
进入
source venv/bin/activate
退出
deactivate
删除
rm -rf venv

3.3 django环境部署
3.3.1 django软件安装
解压
cd /data/soft
tar xf Django。。。
查看
cd Django...
cat INSTALL or README
安装
python setup.py install

python类型软件的安装流程
普通:
解压   安装
特殊:
解压    编译 安装

编译:python setup.py build

3.3.2 django项目操作
创建
django-admin startproject itcast

3.3.3 django应用操作
创建应用
python manager.py startapp test1
注册应用
itcast/settings.py

INSTALL_APP = [
。。。
'test1',
]

3.3.4 view和url配置
view 配置文件生效
root@admina-virtual-machine:/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文件配置
root@admina-virtual-machine:/data/soft# cat /data/server/itcast/itcast/urls.py
"""itcast URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
1. Add an import:  from my_app import views
2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
1. Add an import:  from other_app.views import Home
2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from test1.views import *

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

启动服务:
cd /data/server/itcast
python  manager.py runserver

启动django
python manage.py runserver >> /dev/null 2>&1 &
关闭:
ps aux | grep python
kill 56491

问题:
django项目只能在本机查看

方案:
nginx、haproxy

优中选优
简单

3.4 nginx环境部署
3.4.1 pcre软件安装
解压
tar xf pcre...
查看帮助
cd pcre。。。
INSTALL 或者 README

配置
./configure

编译
make

安装
make install

linux中软件安装的一般流程
解压
tar
解压文件,获取真正的配置文件
配置
configure
根据默认的配置项或者更改配置项,生成编译配置文件(Makefile)
编译
make
根据 Makefile 内容,编译生成指定的软件所需要的所有文件
安装
make install
将编译生成的所有文件,转移到软件指定安装的目录下面
--prefix

3.4.2 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

3.4.3 nginx简单操作

检查
./sbin/nginx -t
开启
./sbin/nginx
关闭
./sbin/nginx -s stop

重载
./sbin/nginx -s reload

突发问题:
root@admina-virtual-machine:/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默认找库文件的路径有问题
5、解决

3.4.4 nginx代理django项目
nginx的目录结构
root@admina-virtual-machine:/data/server/nginx# tree -L 2 /data/server/nginx/
/data/server/nginx/
├── ...
├── conf 配置文件目录
│   ...
│   ├── nginx.conf 默认的配置文件
│   ...
├── ...
├── html 网页文件
│   ├── 50x.html
│   └── index.html
├── logs 日志目录
│   ├── access.log
│   └── error.log
├── ...
├── sbin 执行文件目录
│   └── nginx
├── ...

nginx配置文件介绍
全局配置段
http配置段
server配置段 项目或者应用
location配置段 url配置

需求:
127.0.0.1:8000/hello/

代理配置项
#location ~ \.php$ {
#    proxy_pass   http://127.0.0.1;
#}

编辑配置文件实现代理功能
配置内容
62: location /hello/ {
63: proxy_pass http://127.0.0.1:8000;
64: }

标准配置文件
root@admina-virtual-machine:/data/server/nginx# egrep -vn '#|^$' conf/nginx.conf
3:worker_processes  1;
12:events {
13:    worker_connections  1024;
14:}
17:http {
18:    include       mime.types;
19:    default_type  application/octet-stream;
27:    sendfile        on;
31:    keepalive_timeout  65;
35:    server {
36:        listen       80;
37:        server_name  localhost;
43:        location / {
44:            root   html;
45:            index  index.html index.htm;
46:        }
52:        error_page   500 502 503 504  /50x.html;
53:        location = /50x.html {
54:            root   html;
55:        }
62: location /hello/ {
63: proxy_pass http://127.0.0.1:8000;
64: }
81:    }
119:}

配置文件生效

3.5 调试

4、手工发布代码
需求:
手工方式部署代码
线上主机:56.11
代码仓库:56.12

方案:
获取代码
打包代码
传输代码
关闭应用
解压代码
放置代码
备份老文件
放置新文件
开启应用
检查

实践
获取代码
sed -i 's#1.0#1.1#' django/views.py 
sed -i 's#原内容#替换后内容#g' 文件
分隔符:# / @

打包代码
tar zcf django.tar.gz django
传输代码
scp root@192.168.56.12:/data/code/django.tar.gz ./
关闭应用
关闭nginx应用
/data/server/nginx/sbin/nginx -s stop

关闭django应用
根据端口查看进程号,
lsof -Pti :8000
杀死进程号
kill 56502

解压代码
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/

开启应用
开启django应用
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1
deactivate

开启nginx应用
/data/server/nginx/sbin/nginx

检查
netstat -tnulp | grep :80

5、脚本发布代码
5.1 远程脚本编写
5.1.1 远程命令执行
56.11 让 56.12 执行命令
示例:
root@admina-virtual-machine:/data/server/itcast# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0c:29:b7:e7:b7  
  inet addr:192.168.56.11  Bcast:192.168.56.255  Mask:255.255.255.0
  inet6 addr: fe80::20c:29ff:feb7:e7b7/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:436193 errors:0 dropped:3 overruns:0 frame:0
  TX packets:232980 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000 
  RX bytes:549035735 (549.0 MB)  TX bytes:20894523 (20.8 MB)

lo        Link encap:Local Loopback  
  inet addr:127.0.0.1  Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNING  MTU:65536  Metric:1
  RX packets:1630 errors:0 dropped:0 overruns:0 frame:0
  TX packets:1630 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1 
  RX bytes:137717 (137.7 KB)  TX bytes:137717 (137.7 KB)

root@admina-virtual-machine:/data/server/itcast# ssh root@192.168.56.12 "ifconfig"
eth0      Link encap:Ethernet  HWaddr 00:0c:29:f7:ca:d4  
  inet addr:192.168.56.12  Bcast:192.168.56.255  Mask:255.255.255.0
  inet6 addr: fe80::20c:29ff:fef7:cad4/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:9732 errors:0 dropped:3 overruns:0 frame:0
  TX packets:6918 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000 
  RX bytes:884755 (884.7 KB)  TX bytes:822817 (822.8 KB)

lo        Link encap:Local Loopback  
  inet addr:127.0.0.1  Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNING  MTU:65536  Metric:1
  RX packets:306051 errors:0 dropped:0 overruns:0 frame:0
  TX packets:306051 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1 
  RX bytes:23417793 (23.4 MB)  TX bytes:23417793 (23.4 MB)

5.1.2 远程脚本编写
1、实现简单的功能--- 简单的命令罗列
root@admina-virtual-machine:/data/scripts# cat tar_code.sh 
#!/bin/bash
# 功能:打包代码
# 脚本名:tar_code.sh
# 作者:python 13期全体
# 版本:V 0.1
# 联系方式:长安街1号 太和殿旁边 中南海1号厅

cd /data/code
[ -f django.tar.gz ] && rm -f django.tar.gz
tar zcf django.tar.gz django

2、 脚本优化之 固定内容变量化
root@admina-virtual-machine:/data/scripts# cat tar_code.sh 
#!/bin/bash
# 功能:打包代码
# 脚本名:tar_code.sh
# 作者:python 13期全体
# 版本:V 0.2
# 联系方式:长安街1号 太和殿旁边 中南海1号厅

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

cd "${CODE_DIR}"
[ -f "${FILE}" ] && rm -f "${FILE}"
tar zcf "${FILE}" "${CODE_PRO}"

3、脚本优化之 功能函数化
root@admina-virtual-machine:/data/scripts# cat tar_code.sh 
#!/bin/bash
# 功能:打包代码
# 脚本名:tar_code.sh
# 作者:python 13期全体
# 版本:V 0.3
# 联系方式:长安街1号 太和殿旁边 中南海2号厅

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

code_tar(){
cd "${CODE_DIR}"
[ -f "${FILE}" ] && rm -f "${FILE}"
tar zcf "${FILE}" "${CODE_PRO}"
}
code_tar

5.2 部署脚本编写
5.2.1 脚本框架
需求:先将脚本所设计的所有业务流程跑通

方案:
使用函数来体现

脚本实施:
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:python 13期全体
# 版本:V 0.1
# 联系方式:长安街1号 太和殿旁边 国务院1号厅

# 打包代码
tar_code(){
echo "打包代码"
}

# 传输代码
scp_code(){
echo "传输代码"
}

# 关闭应用
serv_stop(){
echo "关闭nginx应用"
echo "关闭django应用"
}

# 解压代码
untar_code(){
echo "解压代码"
}

# 放置代码
fangzhi_code(){
echo "放置代码"
}

# 开启应用
serv_star(){
echo "开启django应用"
echo "开启nginx应用"
}

# 检查
check(){
echo "检查"
}

main(){
tar_code
scp_code
serv_stop
untar_code
fangzhi_code
serv_star
check
}

main

5.2.2 命令填空
需求:
在流程跑通的情况下,执行完整的代码部署过程

方案:
在流程框架中,填写执行没有任何问题的命令

脚本实施:

#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:python 13期全体
# 版本:V 0.2
# 联系方式:长安街1号 太和殿旁边 国务院2号厅

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

# 传输代码
scp_code(){
echo "传输代码"
cd /data/codes/
[ -f django.tar.gz ] && rm -f django.tar.gz
[ -d django ] && rm -rf django
scp root@192.168.56.12:/data/code/django.tar.gz ./
}

# 关闭应用
serv_stop(){
echo "关闭nginx应用"
/data/server/nginx/sbin/nginx -s stop
echo "关闭django应用"
kill `lsof -Pti :8000`
}

# 解压代码
untar_code(){
echo "解压代码"
cd /data/codes
tar xf django.tar.gz
}

# 放置代码
fangzhi_code(){
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/
}

# 开启应用
serv_star(){
echo "开启django应用"
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
echo "开启nginx应用"
/data/server/nginx/sbin/nginx
}

# 检查
check(){
echo "检查"
netstat -tnulp | grep :80
}

main(){
tar_code
scp_code
serv_stop
untar_code
fangzhi_code
serv_star
check
}

main

5.2.3 增加日志功能
需求:
1、追踪记录
2、数据说话

方案:
增加日志功能
1、日志文件
/data/logs/deploy.log
2、日志格式
日期 时间 脚本名称 步骤

日期:date +%F
时间:date +%T
脚本:$0

脚本实施:
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:python 13期全体
# 版本:V 0.3
# 联系方式:长安街1号 太和殿旁边 国务院3号厅

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

# 增加日志功能
write_log(){
   log_date='date +%F'
   log_time='date +%T'
   buzhou="$1"
   
   echo "${log_date}  ${log_time}  $0  ${buzhou}" >> "${LOG_FILE}"
}

# 打包代码
tar_code(){
echo "打包代码"
ssh root@192.168.56.12 "/bin/bash /data/scripts/tar_code.sh"
write_log "打包代码"
}

# 传输代码
scp_code(){
echo "传输代码"
cd /data/codes/
[ -f django.tar.gz ] && rm -f django.tar.gz
[ -d django ] && rm -rf django
scp root@192.168.56.12:/data/code/django.tar.gz ./
write_log "传输代码"
}

# 关闭应用
serv_stop(){
echo "关闭nginx应用"
/data/server/nginx/sbin/nginx -s stop
write_log "关闭nginx应用"

echo "关闭django应用"
kill `lsof -Pti :8000`
write_log "关闭django应用"
}

# 解压代码
untar_code(){
echo "解压代码"
cd /data/codes
tar xf django.tar.gz
write_log "解压代码"
}

# 放置代码
fangzhi_code(){
echo "备份原文件"
mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S`
write_log "备份原文件"

echo "放置新文件"
mv /data/codes/django/views.py /data/server/itcast/test1/
write_log "放置新文件"
}

# 开启应用
serv_star(){
echo "开启django应用"
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
write_log "开启django应用"

echo "开启nginx应用"
/data/server/nginx/sbin/nginx
write_log "开启nginx应用"
}

# 检查
check(){
echo "检查"
netstat -tnulp | grep :80
write_log "检查"
}

main(){
tar_code
scp_code
serv_stop
untar_code
fangzhi_code
serv_star
check
}

main

5.2.4 增加锁文件功能
需求:
同一时间段内,只允许有一个用户来执行这个脚本
如果脚本执行的时候,有人在执行,那么输入报错:改脚本正在运行......

设计:
锁文件 /tmp/deploy.pid
脚本执行的时候,需要创建锁文件
脚本执行结束的时候,需要删除锁文件

脚本实施
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:python 13期全体
# 版本:V 0.4
# 联系方式:长安街1号 太和殿旁边 国务院4号厅

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

# 增加锁文件
add_lock(){
echo "增加锁文件"
touch /tmp/deploy.pid
write_log "增加锁文件"
}

# 删除锁文件
del_lock(){
echo "删除锁文件"
rm -f /tmp/deploy.pid
write_log "删除锁文件"
}

# 增加日志功能
write_log(){
   log_date='date +%F'
   log_time='date +%T'
   buzhou="$1"
   
   echo "${log_date}  ${log_time}  $0  ${buzhou}" >> "${LOG_FILE}"
}

# 打包代码
tar_code(){
echo "打包代码"
ssh root@192.168.56.12 "/bin/bash /data/scripts/tar_code.sh"
write_log "打包代码"
}

# 传输代码
scp_code(){
echo "传输代码"
cd /data/codes/
[ -f django.tar.gz ] && rm -f django.tar.gz
[ -d django ] && rm -rf django
scp root@192.168.56.12:/data/code/django.tar.gz ./
write_log "传输代码"
}

# 关闭应用
serv_stop(){
echo "关闭nginx应用"
/data/server/nginx/sbin/nginx -s stop
write_log "关闭nginx应用"

echo "关闭django应用"
kill `lsof -Pti :8000`
write_log "关闭django应用"
}

# 解压代码
untar_code(){
echo "解压代码"
cd /data/codes
tar xf django.tar.gz
write_log "解压代码"
}

# 放置代码
fangzhi_code(){
echo "备份原文件"
mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S`
write_log "备份原文件"

echo "放置新文件"
mv /data/codes/django/views.py /data/server/itcast/test1/
write_log "放置新文件"
}

# 开启应用
serv_star(){
echo "开启django应用"
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
write_log "开启django应用"

echo "开启nginx应用"
/data/server/nginx/sbin/nginx
write_log "开启nginx应用"
}

# 检查
check(){
echo "检查"
netstat -tnulp | grep :80
write_log "检查"
}

main(){
if [ -f /tmp/deploy.pid ]
then
echo "脚本 $0 正在运行中....."
exit
else
add_lock
tar_code
scp_code
serv_stop
untar_code
fangzhi_code
serv_star
check
del_lock
fi
}

main

5.2.5 脚本流程知识点填充
需求:
如果我给脚本出入的参数是deploy,那么我才执行
方案;
1、脚本的传参
2、位置参数的调用
3、case流程语句的使用

输出帮助信息:
脚本 $0 的使用方式: $0 [ deploy ]

脚本实施
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:python 13期全体
# 版本:V 0.5
# 联系方式:长安街1号 太和殿旁边 国务院5号厅

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

# 脚本使用帮助
usage(){
echo "脚本 $0 的使用方式: $0 [ deploy ]"
exit
}

# 增加锁文件
add_lock(){
echo "增加锁文件"
touch /tmp/deploy.pid
write_log "增加锁文件"
}

# 删除锁文件
del_lock(){
echo "删除锁文件"
rm -f /tmp/deploy.pid
write_log "删除锁文件"
}

# 增加日志功能
write_log(){
   log_date='date +%F'
   log_time='date +%T'
   buzhou="$1"
   
   echo "${log_date}  ${log_time}  $0  ${buzhou}" >> "${LOG_FILE}"
}

# 打包代码
tar_code(){
echo "打包代码"
ssh root@192.168.56.12 "/bin/bash /data/scripts/tar_code.sh"
write_log "打包代码"
}

# 传输代码
scp_code(){
echo "传输代码"
cd /data/codes/
[ -f django.tar.gz ] && rm -f django.tar.gz
[ -d django ] && rm -rf django
scp root@192.168.56.12:/data/code/django.tar.gz ./
write_log "传输代码"
}

# 关闭应用
serv_stop(){
echo "关闭nginx应用"
/data/server/nginx/sbin/nginx -s stop
write_log "关闭nginx应用"

echo "关闭django应用"
kill `lsof -Pti :8000`
write_log "关闭django应用"
}

# 解压代码
untar_code(){
echo "解压代码"
cd /data/codes
tar xf django.tar.gz
write_log "解压代码"
}

# 放置代码
fangzhi_code(){
echo "备份原文件"
mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S`
write_log "备份原文件"

echo "放置新文件"
mv /data/codes/django/views.py /data/server/itcast/test1/
write_log "放置新文件"
}

# 开启应用
serv_star(){
echo "开启django应用"
source /data/virtual/venv/bin/activate
cd /data/server/itcast/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
write_log "开启django应用"

echo "开启nginx应用"
/data/server/nginx/sbin/nginx
write_log "开启nginx应用"
}

# 检查
check(){
echo "检查"
netstat -tnulp | grep :80
write_log "检查"
}

main(){
case "$1" in
"deploy")
if [ -f /tmp/deploy.pid ]
then
echo "脚本 $0 正在运行中....."
exit
else
add_lock
tar_code
scp_code
serv_stop
untar_code
fangzhi_code
serv_star
check
del_lock
fi
;;
*)
usage
;;
esac
}

main $1

5.2.6 输入参数安全优化
需求:
对脚本传入的参数进行判断,如果传入的参数数量不对,直接提示脚本使用方式,然后退出

方案:
条件表达式 + $#

脚本实施
#!/bin/bash
# 功能:打包代码        
# 脚本名:deploy.sh     
# 作者:python 13期全体 
# 版本:V 0.6
# 联系方式:长安街1号 太和殿旁边 国务院6号厅

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

# 脚本使用帮助
usage(){
echo "脚本 $0 的使用方式: $0 [ deploy ]"
exit
}

[ "$#" -eq 1 ] || usage
...

5.2.7 脚本调试功能

-x

示例:
root@admina-virtual-machine:/data/scripts/python10# bash -x while.sh 
+ a=1
+ '[' 1 -lt 5 ']'
+ echo 1
1
+ a=2
+ '[' 2 -lt 5 ']'
+ echo 2
2
+ a=3
+ '[' 3 -lt 5 ']'
+ echo 3
3
+ a=4
+ '[' 4 -lt 5 ']'
+ echo 4
4
+ a=5
+ '[' 5 -lt 5 ']'

5.3 生产脚本编写总结
5.3.1 简单脚本编写总结
1、命令简单罗列
2、固定的内容变量化
3、功能函数化

5.3.2 复杂脚本编写总结
1、手工执行的命令一定要正确
2、根据流程编写脚本的框架
3、将手工执行的命令填充到对应的框架函数内部
4、增加日志功能,方便跟踪脚本历史执行记录
5、增加锁文件,保证代码发布的过程中,不受同类脚本影响
6、主函数中逻辑流程控制好,
7、设计安全的方面:
输入参数数量
输入参数匹配
脚本帮助信息
8、调试脚本

注意事项:
1、命令一定要保证能正常执行
2、成对的符号,要成对写,避免丢失
3、函数调用,
写好函数后,一定要在主函数中进行调用
4、避免符号出现英文
5、命令变量的写法一定要规范
6、固定的内容一定要变量实现,方便以后更改
7、日志的输出
8、脚本的传参和函数的传参要区别对待

shell--基础语法相关推荐

  1. shell基础语法以及监控进程不存在重启

    转码 # dos2unix ./test.sh 权限 # chmod a+x ./test.sh 语法 变量 var="111" echo $var echo ${var} 运算 ...

  2. Linux shell 基础语法

    常用变量的定义 //定义变量.获取变量值(数值型) $ a=1 $ echo ${a} 1 //定义变量.获取变量值(字符串) $ a="hello world" $ echo $ ...

  3. Linux bash shell基础语法

    转自:http://blog.sina.com.cn/s/blog_46177c3401014fty.html 一.Shell基本类型的变量: (1)Shell定义的环境变量: Shell在开始执行时 ...

  4. Linux Shell 基础语法 流程控制 逻辑运算 字符串操作详细解析

    文章目录 1 shell 简单入门 1.1 shell分类 1.2 shell脚本 1.3 Shell 脚本四种启动方式 2 shell 变量 2.1 普通变量 2.1.1 定义变量 2.1.2 变量 ...

  5. Linux基础、Shell基础语法等

    常用指令 sed 删除redis.conf文件中的空行和注释行 sed -i '/^$/ d' redis.conf sed -i '/^#/ d' redis.conf 文件目录类 df -Th 查 ...

  6. linux shell概述,Linux学习 -- Shell基础 -- 概述

    Shell是什么? 命令解释器 编程语言 Linux支持的Shell类型 cat /etc/shells 主要学习 bash 脚本执行方式 echo echo -e 单引号 -- 原始字符串  双引号 ...

  7. 3000字扫盲shell基础知识(新手必备)

    目录 shell基础语法之变量 shell 变量命名 shell 变量调用 shell 变量分类 shell 运算符 运算符种类 关系运算符 布尔运算符 字符串运算符 逻辑运算符 文件测试运算符 sh ...

  8. Linux云计算之shell 基本语法晚上干肺写出来的

    shell 基本语法 什么是shell? Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户 ...

  9. bash初识,shell的基础语法及基本特性

    1.1 bash初识 1.1.1 什么是bash shell 是一个命令解释器,负责用户程序与内核进行交互操作的一种接口, 将用户输入的命令翻译给操作系统,并将处理后的结果输出至屏幕. 1.1.2 b ...

  10. day23:shell基础介绍 alias及重定向

    2019独角兽企业重金招聘Python工程师标准>>> 1.shell基础介绍: shell是一个命令解释器,用于用户与机器的交互: 也支持特定的语法(逻辑判断,循环): 每个用户都 ...

最新文章

  1. 解决使用Dockerfile来build镜像时pip install遇到的BUG
  2. 一个通用Makefile详解
  3. 不是碰不到更好的,是因为已经有了你!
  4. vmware虚拟机不识别usb设备
  5. android中播放gif动画之二
  6. C语言代替cmd命令
  7. mysql deadlock found when trying to get lock 问题排查
  8. 解决自定义actionbar 两边空隙
  9. Verilog测试:TestBench结构
  10. title和alt属性有什么作用?
  11. 井字棋游戏的实现和注意细节
  12. 为什么电脑屏幕会横过来_电脑屏幕横过来了怎么办
  13. 学术篇 | 面向分类的脑电接口Fuzzy-Rough特征选择
  14. 针对谷氨酰胺运输体的小分子抑制剂
  15. CSS - 移动端布局(一)关键的前置知识
  16. 使用安卓模拟器时提示关闭hyper-v
  17. 根据瘦子的日历,改装了一个月历控件
  18. PHP+MySQL实现精确统计网站访问量(IP个数)
  19. 《MongoDB极简教程》第一章 NoSQL简史 MongoDB安装环境配置
  20. 如何通过接口获取商品详情

热门文章

  1. AI“裸泳”、用户“裸奔”
  2. 如何用pydoc查询函数或模块
  3. Python list 和 numpy 实现 3-sigma 异常值剔除和异常值替换实例
  4. DBeaver21下载与安装教程
  5. CC2530之点亮LED
  6. ai前世识别_抖音AI人脸找出你的前世是谁测试入口-AI人脸找出你的前世是谁官方版入口预约v1.0_信手游...
  7. 全文搜索引擎Elasticsearch入门教程
  8. 0x80070057复制从服务器复制文件,Win10无法切换到本地帐户提示错误0x80070057怎么办?...
  9. 推荐一位年入百万的朋友!
  10. 计算机在往硬盘上写数据时从磁道开始,计算机在往硬盘上写数据时寻道是从( )磁道开始。...