正文共: 6290 字 5 图 预计阅读时间: 16 分钟 注:昨日发布完文章,怎么跑了俩粉丝,本来就几个人,你还跑....老夫甚是心累啊,你快回来~~~~
The death of a dream is the day that you stop believing in the work it takes to get there.
不再相信自己能够成功,就是梦想破碎的时刻。
小闫语录:
支撑一个人前进的,莫过于信念。因为坚信黎明的曙光,所以未曾害怕黑暗。因为心中有你,所以前路尽是温暖。
首先我们通过一个示例来展示单分支if语句:
需求:如果输入的参数为 man
,那么输出您的性别为男。
#!/bin/bash
if [ "$1" == "man" ]
then
echo "您的性别是:男"
fi
我们执行上面的脚本文件:
ethanyan@ethanyan-PC:~$ bash if_test.sh man
您的性别是:男
我们可以通过一个条件的判断,得到不同情况下的结果吗?可以。下面我们就通过一个例子展示双分支if语句:
需求:输入参数 man
,输出您的性别为男,否则输出女性。
#!/bin/bash
if [ "$1" == "man" ]
then
echo "您的性别是:男"
else
echo "您的性别是:女"
fi
我们执行一下这个脚本文件:
ethanyan@ethanyan-PC:~$ bash if_test.sh man
您的性别是:男
ethanyan@ethanyan-PC:~$ bash if_test.sh woman
您的性别是:女
既然有单分支和双分支语句了,那么有多分支语句吗,就好像 elif
这种判断?有。下面我们就通过一个例子展示多分支if语句:
需求:输入参数 man
,输出您的性别为男;输入参数 woman
,输出女;输入其他,输出不知道。
#!/bin/bash
if [ "$1" == "man" ]
then
echo "您的性别是:男"
elif [ "$1" == "woman" ]
then
echo "您的性别是:女"
else
echo "您的性别,臣妾猜不到啊~"
fi
我们执行脚本文件:
ethanyan@ethanyan-PC:~$ bash if_test.sh
您的性别,臣妾猜不到啊~
ethanyan@ethanyan-PC:~$ bash if_test.sh man
您的性别是:男
ethanyan@ethanyan-PC:~$ bash if_test.sh woman
您的性别是:女
需求:我们通过传入的参数不同,实现不同的功能。
参数 | 执行效果 |
---|---|
start | 服务器启动中... |
stop | 服务器关闭中... |
restart | 服务器重启中... |
脚本文件为:
ethanyan@ethanyan-PC:~$ bash if_test.sh stop
服务其正在关闭...
ethanyan@ethanyan-PC:~$ bash if_test.sh start
服务器正在启动...
ethanyan@ethanyan-PC:~$ bash if_test.sh restart
服务器正在重启...
ethanyan@ethanyan-PC:~$ bash if_test.sh
脚本执行方式:bash if_test.sh [ start | stop | restart ]
你有可能说:上面的if判断语句代码量有点多啊。那么我们就来简化一下,用到的就是 case
选择语句。
我们还是以上面的综合案例为例,进行改写。脚本文件如下:
#!/bin/bash
case "$1" in
"start")
echo "服务器正在启动..."
;;
"stop")
echo "服务器正在关闭..."
;;
"restart")
echo "服务正在重启..."
;;
*)
echo "脚本的使用方法:bash $0 [ start | stop | restart ]"
;;
esac
我们执行上面的脚本文件:
ethanyan@ethanyan-PC:~$ bash case_test.sh stop
服务器正在关闭...
ethanyan@ethanyan-PC:~$ bash case_test.sh start
服务器正在启动...
ethanyan@ethanyan-PC:~$ bash case_test.sh restart
服务正在重启...
ethanyan@ethanyan-PC:~$ bash case_test.sh
脚本的使用方法:bash case_test.sh [ start | stop | restart ]
需求:循环遍历当前文件夹下的文件。
#!/bin/bash
for i in $(ls ./)
do
echo "${i}"
done
执行结果:
ethanyan@ethanyan-PC:~$ bash for_test
case_test.sh
for_test.sh
if_test.sh
...
格式:
while 条件
do
执行语句
done
注意:条件的类型:命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
示例:a初始值为1,不断 +1
操作,直到a不小于5为止。
#!/bin/bash
a=1
while [ "${a}" -lt 5 ]
do
echo "${a}"
a=$((a+1))
done
执行上面的脚本文件:
ethanyan@ethanyan-PC:~$ bash while.sh
1
2
3
4
格式:
until 条件
do
执行语句
done
注意:条件的类型:命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
示例:a初始值为1,不断进行 +1
操作,直到a等于5为止。
#!/bin/bash
a=1
until [ "${a}" -eq 5 ]
do
echo "${a}"
a=$((a+1))
done
执行上面的脚本:
ethanyan@ethanyan-PC:~$ bash util.sh
1
2
3
4
先来一个简单的函数,无参数。用于执行频繁的指令。我们封装一些常用指令,只需调用函数即可。
#!/bin/bash
# 定义函数
func1(){
echo "my name is ethanyan"
}
# 调用函数
func1
:<<!
我们可以在函数中封装常用指令
此处只是做一个简单的示例
!
执行上面的脚本:
ethanyan@ethanyan-PC:~$ bash fun1.sh
my name is ethanyan
注意:在调用函数的时候没有括号。脚本文件中所有的标点符号均为英文状态下。
实现函数传参和函数体内调用参数,脚本文件示例:
#!/bin/bash
func2(){
echo "my name is $1"
}
# 调用函数并传参
func2 ethanyan
执行脚本文件:
ethanyan@ethanyan-PC:~$ bash func2.sh
my name is ethanyan
实现脚本传参,函数调用。脚本文件示例:
#!/bin/bash
func3(){
echo "my name is $1"
}
func3 $1
执行脚本:
ethanyan@ethanyan-PC:~$ bash func3.sh ethanyan
my name is ethanyan
还有一种脚本传参的方式,这种情况在生产环境下使用:
#!/bin/bash
name="$1"
func4(){
echo "my name is $1"
}
func4 "${name}"
执行脚本:
ethanyan@ethanyan-PC:~$ bash func4.sh ethanyan
my name is ethanyan
文件压缩:
tar -zcvf 压缩后的文件名 压缩的文件
文件解压到当前路径:
tar -zxvf 要解压的文件
参数 | 作用 |
---|---|
z | 指定压缩文件的格式为 tar.gz |
c | 压缩 |
v | 显示详细过程 |
f | 指定压缩文件 |
x | 解压 |
查看压缩文件内容:
zcat 压缩文件
上面压缩与解压缩的格式为常用的
gz
压缩格式。当然还有zip
和bz2
两种格式。
将本地的文件推送到远程的服务器:
scp 本地文件名 用户名@ip:远程目录
将远程服务器上的文件拉取到本地:
scp 用户名@ip:远程文件 本地目录
如果传输的是目录,不是文件,需要指定参数 -r
,如下:
scp -r 本地目录名 用户名@ip:远程目录
可以使用 cp
命令来进行操作,但是为了避免放置新文件的时候,出现验证操作,常采用 mv
命令,如下:
mv test.txt test-$(date +%Y%m%d%H%M%S)
此处是将文件直接重命名而已,加了一个时间戳。当然你可以采用压缩进行备份;或者将文件复制一份,一份作为备份一份继续使用。根据场景自己选择。
格式:
date [option]
参数 | 作用 |
---|---|
%F | 显示当前日期格式,%Y-%m-%d |
%T | 显示当前时间格式,%H:%M:%S |
使用效果:
ethanyan@ethanyan-PC:~$ date +%F
2019-04-05
ethanyan@ethanyan-PC:~$ date +%T
15:58:06
当然我们在给文件加时间戳的时候,希望是一串数字,没有特殊符号。下面代码即可实现:
date命令获取的都是当前系统的时间。
ethanyan@ethanyan-PC:~$ date +%Y%m%d
20190405 # 显示年月日
ethanyan@ethanyan-PC:~$ date +%H%M%S
160301 # 显示时分秒
ethanyan@ethanyan-PC:~$ date +%Y%m%d%H%M%S
20190405160403 # 显示年月日时分秒
为了方便项目管理,需要创建基础环境目录。
起名要做到见名知意。
下面举一个例子:
1.创建基本目录:
mkdir ./data/{server,logs,backup,softs,virtual,scripts,codes} -p
-p
为创建层级目录。
2.查看创建的目录结构:
ethanyan@ethanyan-PC:~$ tree -L 1 ./data/
./data/
├── backup # 备份
├── codes # 代码
├── logs # 日志
├── scripts # 脚本文件
├── server # 服务
├── softs # 软件
└── virtual # 虚拟环境
tree命令需要安装,用来查看目录树状结构。
-L
参数指定显示的层级,我们指定为显示1层。
我们在与主机进行文件传输的时候,每次链接都会进行密码验证,如果是手工的话,可以登录。自动化部署的时候,脚本却无能为力。那么有什么办法吗?答案就是进行免密钥认证操作。
方案思路:
1.本机生成密钥对;
2.对端机器使用公钥文件认证;
3.验证。
方案实施:
1.在本机生成密钥对:
ssh-keygen -t rsa
-t
:指定密钥类型。rsa
:密钥类型。密钥目录:
/root/.ssh/
id_rsa
:私钥。id_rsa.pub
:公钥。2.将 .pub
公钥文件复制到对端机器的目录中,并改名为 authorized_keys
,文件路径展示:
/root/.ssh/authorized_keys
3.在对端机器中,编辑 ssh
配置文件:
/etc/ssh/sshd_config
将下面一行的注释取消掉:
AuthorizedKeysFile %h/.ssh/authorized_keys
4.在对端机器重启ssh服务:
/etc/init.d/ssh restart
5.在本机进行连接,验证操作:
ssh root@192.168.8.15
需求:部署一个环境,支持django项目正常运行。
需求分析,部署方案:
1.进行django环境部署:
1.1 python虚拟环境
1.2 django环境部署
1.2.1 django软件安装
1.2.2 项目基本操作
1.2.3 应用基本操作
1.2.4 view和url配置
1.2.5问题:只有本机才能访问
1.2.6方案代理 --> nginx
2.nginx代理django:
2.1 nginx软件安装
2.1.1 pcre软件安装
2.1.2 nginx软件安装
2.1.3 nginx基本操作
2.2 nginx代理配置
2.2.1 目录结构查看
2.2.2 配置文件查看
2.2.3 编辑代理配置项
3.项目调试:
3.1 启动软件
3.1.1 启动django
3.1.2 启动nginx
3.2 整个项目调试
最后就是根据方案对项目进行部署。
一般的脚本大家都会写了,那么对于线上服务器的大型脚本是如何实现的呢?我们先来看一下流程:
1.编写脚本框架。 (处处有框架,脚本也不例外,但是此框架需要自己实现)
2.用命令对脚本框架进行填充。
3.完善功能(增加日志功能;增加锁文件功能;增加主函数逻辑;增加参数安全措施)。
下面是编写一个简单的脚本框架,大家可以仿照书写:
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:ethanyan
# 版本:V 0.1
# 联系方式:donnotcallme@163.com
# 获取代码
get_code(){
echo "获取代码"
}
# 打包代码
tar_code(){
echo "打包代码"
}
# 传输代码
scp_code(){
echo "传输代码"
}
# 关闭应用
stop_serv(){
echo "关闭应用"
echo "关闭nginx应用"
echo "关闭django应用"
}
# 解压代码
untar_code(){
echo "解压代码"
}
# 放置代码
lay_code(){
echo "放置代码"
echo "备份老文件"
echo "放置新文件"
}
# 开启应用
start_serv(){
echo "开启应用"
echo "开启django应用"
echo "开启nginx应用"
}
# 检查
check(){
echo "检查项目"
}
# 部署函数
deploy_pro(){
get_code
tar_code
scp_code
stop_serv
untar_code
lay_code
start_serv
check
}
# 主函数
main(){
deploy_pro
}
# 执行主函数
main
剩下的大家可以填充,完善等。
优质文章推荐: