前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shell(二)

shell(二)

作者头像
小闫同学啊
发布2019-07-18 15:16:52
9410
发布2019-07-18 15:16:52
举报
文章被收录于专栏:小闫笔记小闫笔记

正文共: 6290 字 5 图 预计阅读时间: 16 分钟 注:昨日发布完文章,怎么跑了俩粉丝,本来就几个人,你还跑....老夫甚是心累啊,你快回来~~~~

每日分享

The death of a dream is the day that you stop believing in the work it takes to get there.

不再相信自己能够成功,就是梦想破碎的时刻。

小闫语录

支撑一个人前进的,莫过于信念。因为坚信黎明的曙光,所以未曾害怕黑暗。因为心中有你,所以前路尽是温暖。

shell(二)

1.shell流程控制

1.1简单流程控制语句

1.1.1if判断语句

首先我们通过一个示例来展示单分支if语句:

需求:如果输入的参数为 man,那么输出您的性别为男。

代码语言:javascript
复制
#!/bin/bash
if [ "$1" == "man" ]
then
    echo "您的性别是:男"
fi

我们执行上面的脚本文件:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash if_test.sh man
您的性别是:男

我们可以通过一个条件的判断,得到不同情况下的结果吗?可以。下面我们就通过一个例子展示双分支if语句:

需求:输入参数 man,输出您的性别为男,否则输出女性。

代码语言:javascript
复制
#!/bin/bash
if [ "$1" == "man" ]
then
    echo "您的性别是:男"
else
    echo "您的性别是:女"
fi

我们执行一下这个脚本文件:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash if_test.sh man
您的性别是:男
ethanyan@ethanyan-PC:~$ bash if_test.sh woman
您的性别是:女

既然有单分支和双分支语句了,那么有多分支语句吗,就好像 elif这种判断?有。下面我们就通过一个例子展示多分支if语句:

需求:输入参数 man,输出您的性别为男;输入参数 woman,输出女;输入其他,输出不知道。

代码语言:javascript
复制
#!/bin/bash
if [ "$1" == "man" ]
then
    echo "您的性别是:男"
elif [ "$1" == "woman" ]
then
    echo "您的性别是:女"
else
    echo "您的性别,臣妾猜不到啊~"
fi

我们执行脚本文件:

代码语言:javascript
复制
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

服务器重启中...

脚本文件为:

代码语言:javascript
复制
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 ]
1.1.2case选择语句

你有可能说:上面的if判断语句代码量有点多啊。那么我们就来简化一下,用到的就是 case选择语句。

我们还是以上面的综合案例为例,进行改写。脚本文件如下:

代码语言:javascript
复制
#!/bin/bash
case "$1" in 
    "start")
        echo "服务器正在启动..."
        ;;
    "stop")
        echo "服务器正在关闭..."
        ;;
    "restart")
        echo "服务正在重启..."
        ;;
    *)
        echo "脚本的使用方法:bash $0 [ start | stop | restart ]"
        ;;
esac

我们执行上面的脚本文件:

代码语言:javascript
复制
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 ]
1.1.3for循环语句

需求:循环遍历当前文件夹下的文件。

代码语言:javascript
复制
#!/bin/bash
for i in $(ls ./)
do
    echo "${i}"
done

执行结果:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash for_test 
case_test.sh
for_test.sh
if_test.sh
...
1.1.4while循环语句

格式

代码语言:javascript
复制
while 条件
do
   执行语句
done

注意:条件的类型:命令、[[ 字符串表达式 ]]、(( 数字表达式 ))

示例:a初始值为1,不断 +1操作,直到a不小于5为止。

代码语言:javascript
复制
#!/bin/bash
a=1
while [ "${a}" -lt 5 ]
do
    echo "${a}"
    a=$((a+1))
done

执行上面的脚本文件:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash while.sh 
1
2
3
4
1.1.5until循环语句

格式

代码语言:javascript
复制
until 条件
do
   执行语句
done

注意:条件的类型:命令、[[ 字符串表达式 ]]、(( 数字表达式 ))

示例:a初始值为1,不断进行 +1操作,直到a等于5为止。

代码语言:javascript
复制
#!/bin/bash
a=1
until [ "${a}" -eq 5 ]
do
    echo "${a}"
    a=$((a+1))
done

执行上面的脚本:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash util.sh 
1
2
3
4

2.函数

2.1简单函数

先来一个简单的函数,无参数。用于执行频繁的指令。我们封装一些常用指令,只需调用函数即可。

代码语言:javascript
复制
#!/bin/bash
# 定义函数
func1(){
    echo "my name is ethanyan"
}
# 调用函数
func1
:<<!
我们可以在函数中封装常用指令
此处只是做一个简单的示例
!

执行上面的脚本:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash fun1.sh 
my name is ethanyan

注意:在调用函数的时候没有括号。脚本文件中所有的标点符号均为英文状态下。

2.2函数传参

实现函数传参和函数体内调用参数,脚本文件示例:

代码语言:javascript
复制
#!/bin/bash
func2(){
    echo "my name is $1"
}
# 调用函数并传参
func2 ethanyan

执行脚本文件:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash func2.sh 
my name is ethanyan

2.3脚本传参

实现脚本传参,函数调用。脚本文件示例:

代码语言:javascript
复制
#!/bin/bash
func3(){
    echo "my name is $1"
}
func3 $1

执行脚本:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash func3.sh ethanyan
my name is ethanyan

还有一种脚本传参的方式,这种情况在生产环境下使用:

代码语言:javascript
复制
#!/bin/bash
name="$1"
func4(){
    echo "my name is $1"
}
func4 "${name}"

执行脚本:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ bash func4.sh ethanyan
my name is ethanyan

3.linux命令回顾

3.1压缩与解压缩-gz

文件压缩:

代码语言:javascript
复制
tar -zcvf 压缩后的文件名 压缩的文件

文件解压到当前路径:

代码语言:javascript
复制
tar -zxvf 要解压的文件

参数

作用

z

指定压缩文件的格式为 tar.gz

c

压缩

v

显示详细过程

f

指定压缩文件

x

解压

查看压缩文件内容:

代码语言:javascript
复制
zcat 压缩文件

上面压缩与解压缩的格式为常用的 gz压缩格式。当然还有 zipbz2两种格式。

3.2文件传输

将本地的文件推送到远程的服务器:

代码语言:javascript
复制
scp 本地文件名 用户名@ip:远程目录

将远程服务器上的文件拉取到本地:

代码语言:javascript
复制
scp 用户名@ip:远程文件 本地目录

如果传输的是目录,不是文件,需要指定参数 -r,如下:

代码语言:javascript
复制
scp -r 本地目录名 用户名@ip:远程目录

3.3文件备份

可以使用 cp命令来进行操作,但是为了避免放置新文件的时候,出现验证操作,常采用 mv命令,如下:

代码语言:javascript
复制
mv test.txt test-$(date +%Y%m%d%H%M%S)

此处是将文件直接重命名而已,加了一个时间戳。当然你可以采用压缩进行备份;或者将文件复制一份,一份作为备份一份继续使用。根据场景自己选择。

3.3.1date命令:

格式

代码语言:javascript
复制
date [option]

参数

作用

%F

显示当前日期格式,%Y-%m-%d

%T

显示当前时间格式,%H:%M:%S

使用效果:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ date +%F
2019-04-05
ethanyan@ethanyan-PC:~$ date +%T
15:58:06

当然我们在给文件加时间戳的时候,希望是一串数字,没有特殊符号。下面代码即可实现:

date命令获取的都是当前系统的时间。

代码语言:javascript
复制
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  # 显示年月日时分秒

4.环境部署

4.1基础目录环境

为了方便项目管理,需要创建基础环境目录。

起名要做到见名知意。

下面举一个例子:

1.创建基本目录:

代码语言:javascript
复制
mkdir ./data/{server,logs,backup,softs,virtual,scripts,codes} -p

-p为创建层级目录。

2.查看创建的目录结构:

代码语言:javascript
复制
ethanyan@ethanyan-PC:~$ tree -L 1 ./data/
./data/
├── backup    # 备份
├── codes    # 代码
├── logs    # 日志
├── scripts    # 脚本文件
├── server    # 服务
├── softs    # 软件
└── virtual    # 虚拟环境

tree命令需要安装,用来查看目录树状结构。 -L参数指定显示的层级,我们指定为显示1层。

4.2免密登录设置

我们在与主机进行文件传输的时候,每次链接都会进行密码验证,如果是手工的话,可以登录。自动化部署的时候,脚本却无能为力。那么有什么办法吗?答案就是进行免密钥认证操作。

方案思路

1.本机生成密钥对;

2.对端机器使用公钥文件认证;

3.验证。

方案实施

1.在本机生成密钥对:

代码语言:javascript
复制
ssh-keygen -t rsa
  • -t:指定密钥类型。
  • rsa:密钥类型。

密钥目录:

代码语言:javascript
复制
/root/.ssh/
  • id_rsa:私钥。
  • id_rsa.pub:公钥。

2.将 .pub公钥文件复制到对端机器的目录中,并改名为 authorized_keys,文件路径展示:

代码语言:javascript
复制
/root/.ssh/authorized_keys

3.在对端机器中,编辑 ssh配置文件:

代码语言:javascript
复制
/etc/ssh/sshd_config

将下面一行的注释取消掉:

代码语言:javascript
复制
AuthorizedKeysFile    %h/.ssh/authorized_keys

4.在对端机器重启ssh服务:

代码语言:javascript
复制
/etc/init.d/ssh restart

5.在本机进行连接,验证操作:

代码语言:javascript
复制
ssh root@192.168.8.15

4.3方案分析

需求:部署一个环境,支持django项目正常运行。

需求分析,部署方案

1.进行django环境部署:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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.项目调试:

代码语言:javascript
复制
3.1 启动软件
    3.1.1 启动django
    3.1.2 启动nginx
3.2 整个项目调试

最后就是根据方案对项目进行部署。

5.生产脚本

5.1大型脚本编写

一般的脚本大家都会写了,那么对于线上服务器的大型脚本是如何实现的呢?我们先来看一下流程:

1.编写脚本框架。 (处处有框架,脚本也不例外,但是此框架需要自己实现)

2.用命令对脚本框架进行填充。

3.完善功能(增加日志功能;增加锁文件功能;增加主函数逻辑;增加参数安全措施)。

下面是编写一个简单的脚本框架,大家可以仿照书写:

代码语言:javascript
复制
#!/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

剩下的大家可以填充,完善等。

5.2生产脚本编写总结

  • 生产简单脚本的编写流程:命令可执行-命令罗列-内容变量-功能函数-远程执行。
  • 生产大型脚本的编写流程:脚本框架-命令填充-安全完善。
  • 大型脚本的安全功能完善:由内到外,功能安全-流程安全。
  • 掌握 脚本调试方法 语法-n ,追踪-x。
5.2.1简单脚本编写
  • 手工执行的命令一定要可执行。
  • 命令简单罗列。
  • 固定的内容变量化。
  • 功能函数化。
5.2.2复杂脚本编写
  • 手工执行的命令一定要可执行。
  • 根据发布流程编写脚本的框架。
  • 将手工执行的命令填充到对应的框架函数内部。
  • 增加日志功能,方便跟踪脚本历史执行记录。
  • 主函数中逻辑流程控制好。
  • 设计安全的方面:增加锁文件,保证代码发布的过程中不受干扰;判断输入参数数量;匹配输入参数;提供脚本帮助信息。
  • 调试脚本。
5.2.3注意事项
  • 命令一定要保证能正常执行。
  • 成对的符号,要成对写,避免丢失。
  • 函数调用。写好函数后,一定要在主函数中进行调用。
  • 避免符号出现中文。
  • 命令变量的写法一定要规范。
  • 固定的内容一定要变量实现,方便以后更改。
  • 日志的输出。
  • 脚本的传参和函数的传参要区别对待。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

Django相关知识点回顾

美多商城项目导航帖

项目重要技术点介绍

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • shell(二)
    • 1.shell流程控制
      • 1.1简单流程控制语句
    • 2.函数
      • 2.1简单函数
      • 2.2函数传参
      • 2.3脚本传参
    • 3.linux命令回顾
      • 3.1压缩与解压缩-gz
      • 3.2文件传输
      • 3.3文件备份
    • 4.环境部署
      • 4.1基础目录环境
      • 4.2免密登录设置
      • 4.3方案分析
    • 5.生产脚本
      • 5.1大型脚本编写
      • 5.2生产脚本编写总结
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档